diff --git a/kernel/rv1106-enablement/dts/rv1106-warden.dts b/kernel/rv1106-enablement/dts/rv1106-warden.dts index 9625087..7488843 100644 --- a/kernel/rv1106-enablement/dts/rv1106-warden.dts +++ b/kernel/rv1106-enablement/dts/rv1106-warden.dts @@ -23,6 +23,13 @@ device_type = "memory"; reg = <0x00000000 0x10000000>; /* 256 MiB */ }; + + /* --- M5: AIC8800DC wifi/BT power sequencing --- */ + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + }; }; /* --- console --- */ @@ -39,6 +46,22 @@ status = "okay"; }; +/* --- M5: AIC8800DC wifi/BT SDIO (on &sdmmc, mmc@ffaa0000 — NOT &sdio) --- */ +&sdmmc { + max-frequency = <50000000>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + non-removable; + rockchip,default-sample-phase = <90>; + supports-sdio; + mmc-pwrseq = <&sdio_pwrseq>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>; + status = "okay"; +}; + /* --- batch 1: mainline peripherals (wire DT + config) --- */ &uart1 { status = "okay"; diff --git a/kernel/rv1106-enablement/wifi/PORT-PLAN.md b/kernel/rv1106-enablement/wifi/PORT-PLAN.md new file mode 100644 index 0000000..895dfa7 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/PORT-PLAN.md @@ -0,0 +1,569 @@ +# AIC8800 WiFi+BT SDIO driver — 5.10 → 6.18 port plan + +Target: the M5 milestone of `../PORT-STATUS.md` / `../../docs/bringup.md` — port +the AIC8800 SDIO WiFi+BT driver onto the self-built **Linux 6.18.46** kernel that +already boots WardenOS on `warden-c8a3` (M0–M3 done; M4 display in progress). No +plan44 code (per the 2026-08-23 decision in `bringup.md`) — this is a direct +forward-port of our own vendor source, same method already proven for +clk/pinctrl/mach/mmc. + +## 0. Source recommendation + +**Port from our own vendor SDK source**, not from any external fork: +`flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/` (§1 below is the full map). This +is not a default-to-what-we-have choice — it's the correct one on the evidence: + +- **Nothing more upstream exists.** AICSemi has no public upstream driver repo + with a stable, discoverable URL, and there is no aic8800 code in Linux + `staging` or any LKML patch series (mainline/staging status: **absent** — + confirmed by a dedicated web-research pass; no counter-evidence found). + There is nothing more "canonical" to port from than the vendor source we + already have. +- **Our tree already carries two hardware-verified fixes newer forks don't + have**: the `queue_sz`-zero console-flood clamp + (`flare-edge/*/sdk-patches/wifi/patches/0001-aic8800dc-no-zero-timeout-spin-and-ratelimit.patch`) + and the SDIO-wakeup busy-spin→sleep Tier-1 hardening (live in the vendor tree + today per `luckfox-pico-86-panel/wifi-bluetooth-aic8800.md`, tracked as + `future-features-2/sdk-patches/wifi/patches/0002-aic8800dc-sdio-wakeup-sleep-not-spin.patch` + — **not yet copied into this branch's `sdk-patches/`; carry both forward into + the ported tree, and file the housekeeping gap separately**). Starting from a + third-party fork would mean re-discovering and re-fixing both bugs on + hardware. +- **The vendor source already anticipates part of the delta.** `rwnx_compat.h` + has `#if LINUX_VERSION_CODE` shims up to `KERNEL_VERSION(5, 15, 60)` — e.g. + `rwnx_main.c`'s `net_device_ops` already switches between `.ndo_do_ioctl` and + `.ndo_siocdevprivate` at the 5.15 boundary (rwnx_main.c:1457–1474). That + removes one whole item from the delta checklist below at zero cost. +- **A cleaner community fork exists but is not itself a base — it's a reference.** + `radxa-pkg/aic8800` (github.com/radxa-pkg/aic8800) is an actively maintained, + GPL-3.0, DKMS-packaged build of the same AICSemi driver family, explicitly + patched for kernel **6.12/6.13** on Rockchip SDIO boards (Rock 3C/5C), and is + the only community effort found that has already absorbed the post-5.15 + cfg80211/netdev/timer churn this port needs. **Use it the same way the + pinctrl port used the upstream RV1106 patch series — as a correctness + oracle to diff against**, not as code we vendor: it targets AIC8800D80 SDIO/USB/PCIe + variants generically, not our AIC8800DC + our two local hardening patches, + and an Armbian forum thread reports open regressions on it at the 6.12+ + boundary — so treat its fixes as a second opinion on the wiphy-lock and + timer-rename hunks, verify each independently. +- **No mainline/staging path exists to lean on instead.** Confirmed by the + research pass: no aic8800 in `drivers/net/wireless/`, `staging/`, or any + LKML series. This matches the driver-parity table's row (`AIC8800 wifi + (bsp/fdrv) | out-of-tree`) and the bring-up doc's framing: "AIC8800 wifi + (plan44 has none; ours)." + +## 1. SDK source map + +Vendor tree root: `flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/` (an **out-of-tree** +external-module build against `KDIR := ../../../source/kernel`, i.e. the vendor +5.10.160 tree at `flare-edge/sdk/sysdrv/source/kernel/`). Selected by +`RK_ENABLE_WIFI_CHIP=AIC8800DC` in +`flare-edge/sdk/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_86Panel-IPC.mk:138`, +dispatched by `sdk/sysdrv/drv_ko/wifi/Makefile`'s `build-sdio` target +(`ifneq ($(findstring $(RK_ENABLE_WIFI_CHIP),"AIC8800DC"),) @make -C aic8800dc/`). +`88,601` total lines across the three sub-drivers. + +``` +aic8800dc/ + Kconfig # AIC_WLAN_SUPPORT, AIC_FW_PATH (default "/oem/usr/ko/aic8800dc_fw") + # sources drivers/net/wireless/aic8800/{aic8800_fdrv,aic8800_btlpm}/Kconfig + # -- note this path is ALREADY the mainline drivers/net/wireless/ + # convention; the vendor Kconfig assumes it, easing the in-tree move. + Makefile # obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/ + # obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/ + # obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/ + # (link order = bsp, fdrv, btlpm — matches the insmod order below) + aic8800_bsp/ # SDIO bus glue + firmware bootstrap ("bsp" = board support package) + aic_bsp_main.c # module_init/exit; per-chip firmware filename tables (fw_u02, + # fw_8800dc_u01, fw_8800dc_u02, ...); aicbsp_probe_semaphore + aicsdio.c # struct sdio_driver aicbsp_sdio_driver; SDIO_DEVICE_CLASS(WLAN) + # wildcard match + internal vendor/device ID probe: + # SDIO_VENDOR_ID_AIC8800DC=0xc8a1, SDIO_DEVICE_ID_AIC8800DC=0xc08d + # (aicsdio.c:75,80); calls rockchip_wifi_power()/ + # rockchip_wifi_set_carddetect() (aicsdio.c:515-580) — see §3.7 + aic8800dc_compat.c/.h, aic8800d80_compat.c/.h # per-chip-variant glue + aicwf_txq_prealloc.c, md5.c, aic_bsp_driver.c/.h, aicwf_firmware_array.c/.h + aic8800_fdrv/ # the actual cfg80211 full-MAC driver ("fdrv" = fullmac driver) + rwnx_main.c # struct cfg80211_ops rwnx_cfg80211_ops (line 5365); wiphy_new() + # (5732), wiphy_register() (6035); struct net_device_ops + # rwnx_netdev_ops (1457) / rwnx_netdev_monitor_ops (1477); + # 3 rtnl_lock()/rtnl_unlock() pairs (5429,6063,6097) + rwnx_msg_rx.c # firmware→driver event handling incl. cfg80211_connect_result() + # (line 958) and cfg80211_roamed() (1006,1010) + rwnx_cfgfile.c, rwnx_tx.c, rwnx_rx.c, rwnx_txq.c # datapath + aicwf_sdio.c # the actual SDIO transport (`aicwf_sdio_driver`, line 1216) — + # THIS is the file the task's "aicwf_sdio" driver name refers to; + # it lives inside aic8800_fdrv/, not a separate directory. Also + # calls rockchip_wifi_power()/set_carddetect() (1260-1331) and + # contains the Tier-1 wakeup-sleep hardening (§0) around the + # `aicwf_sdio_wakeup()` retry loop (~line 1363 in the older + # line numbering cited by the wiki; grep for `usleep_range`). + aicwf_tcp_ack.c, aicwf_rx_prealloc.c, aic_priv_cmd.c, aic_vendor.c + rwnx_compat.h # vendor compat shim layer, #if LINUX_VERSION_CODE guards up to + # 5.15.60 ONLY — everything past that (timer renames, wiphy + # locking, netif_rx_ni removal) is new territory, not covered. + usb_host.c/.h, rwnx_pci.*, rwnx_mesh.* # dead code on this board (no USB/PCI variant used) + aic8800_btlpm/ # Bluetooth low-power-mode / HCI wake companion module + aic8800_btlpm.c, aic_bluetooth_main.c, lpm.c, rfkill.c # standard rfkill_register(), no + # Rockchip-specific RFKILL_RK dependency (checked, none found) + aic8800dc_fw/ # firmware blobs, see §5 +``` + +**Modules actually `insmod`ed on the running 5.10 panel** (from +`sdk/sysdrv/drv_ko/wifi/insmod_wifi.sh:109-124`, the `#aic8800` stanza gated on +`/proc/device-tree/model` containing `"W"` or an SDIO uevent match): +``` +cfg80211.ko → libarc4.ko → ctr.ko → ccm.ko → libaes.ko → aes_generic.ko + → aic8800_bsp.ko (sleep 0.2s) → aic8800_fdrv.ko (sleep 2s) → aic8800_btlpm.ko (sleep 0.1s) +``` +`rkwifi_server` is deliberately never started (WardenOS owns `wlan0` directly — +see `insmod_wifi.sh:126-137` and `wifi-bluetooth-aic8800.md`); nothing to +replicate there. The crypto modules (arc4/ctr/ccm/aes) are dependencies of the +driver's internal key-handling, not aic8800-specific — confirm they're already +`=y`/reachable in the 6.18 config (crypto is currently listed as "⬜ batch2" in +`../DRIVER-PARITY.md`; flip alongside this work). + +**DT node — correction to the task's framing.** The task description assumed +`sdio: mmc@ff9a0000`. **That is wrong for this board.** The AIC8800 is wired to +**`sdmmc: mmc@ffaa0000`** (mmc1), not `sdio: mmc@ff9a0000` (mmc2) — confirmed +directly in `rv1106g-luckfox-pico-86panel.dts:83-97` (comment literally reads +`/**********SDIO-WIFI**********/` over the `&sdmmc` node) and independently in +`luckfox-pico-86-panel/wifi-bluetooth-aic8800.md:11`/`hardware-86-panel.md:69`. +`&sdio` (mmc@ff9a0000) stays `status = "disabled"` and is unused on this board. +There is **no separate DT child node** for the aic8800 chip itself — it's +discovered purely by SDIO bus-scan + vendor/device ID match inside the driver +(`aicsdio.c`, no `of_match_table` anywhere in the tree — checked, none found); +the only DT surface is the MMC controller node plus the power-sequencing node: +```dts +sdio_pwrseq: sdio-pwrseq { /* rv1106g-luckfox-pico-86panel.dts:20-23 */ + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; +}; +&sdmmc { /* rv1106g-luckfox-pico-86panel.dts:83-97 */ + max-frequency = <50000000>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + non-removable; + rockchip,default-sample-phase = <90>; + supports-sdio; + mmc-pwrseq = <&sdio_pwrseq>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>; + status = "okay"; +}; +``` +The `sdmmc0_{clk,cmd,bus4,det}` pin groups are defined in +`sdk/sysdrv/source/kernel/arch/arm/boot/dts/rv1106-pinctrl.dtsi:700-731` (a +separate include from `rv1106.dtsi`) — port that block, it isn't in the DT +files the M1–M3 work already ported. + +## 2. Open-source landscape (web research) + +- **AICSemi upstream**: no discoverable, stable public GitHub org/repo carrying + aic8800_bsp/fdrv/btlpm as canonical upstream — vendor releases exist only + as SoC-vendor SDK drops (Rockchip's, in our case). Nothing more upstream to + point at than what we have. +- **Mainline/staging**: **absent.** No aic8800 anywhere in `drivers/net/wireless/`, + `drivers/staging/`, or any LKML/patchwork series as of this research pass. +- **Cleanest newer-kernel fork found**: `radxa-pkg/aic8800` + (github.com/radxa-pkg/aic8800) — actively maintained, GPL-3.0, DKMS-packaged, + patched for kernel **6.12/6.13** on Rockchip SDIO boards (Radxa Rock 3C/5C), + covering SDIO/USB/PCIe AIC8800D80 variants. Firmware ships as a companion + `aic8800-firmware` package into `/lib/firmware/aic8800_fw/`. Treat as a + **reference/oracle for the API-delta hunks** (§3), not a vendoring source — + see §0 for why. An Armbian forum thread ("AIC8800 wifi sdio module not + working with kernel 6.12+") reports it has its own open regressions at that + boundary, so cross-check rather than trust each hunk blindly. +- **Other community efforts** (Armbian, LuckFox's own OpenWrt branch, generic + BananaPi/OpenWrt feeds): no aic8800 kmod bundled by default even where the DT + wiring exists — `luckfox-pico-86-panel/alternative-bsps.md:20` documents this + exact gap for LuckFox's own OpenWrt target (`cortexa7.mk` ships `kmod-rknpu-rockchip` + only, no `kmod-aic8800`). Confirms there is no ready-made newer-kernel package + to pull instead of porting. +- **plan44's OpenWrt RV1106 fork** (`flare-edge/research/plan44-openwrt/`, + Linux 6.6, 152 RV1106 patches): checked directly — **contains no aic8800 + code at all** (`find ... -ipath '*aic8800*'` empty). Confirms + `bringup.md`'s "AIC8800 wifi (plan44 has none; ours)" and the "no plan44 + code" decision doesn't cost us anything here — there's nothing to take. + +## 3. 5.10 → 6.18 API-delta checklist + +Grounded in two passes: (a) direct kernel.org/bootlin/LWN research on 5.10→6.18 +API history, (b) `grep` evidence from the actual vendor source (file:line cited +below) so this is a checklist against *our* code, not a generic survey. + +### 3.1 Timers — confirmed hard breaks, exact call sites found +`del_timer_sync`/`del_timer` → **`timer_delete_sync`/`timer_delete`**: renamed +in `9b13df3fb64e` (landed v6.2-rc1) as a **compat-wrapped** rename; **the +compat wrapper was removed in v6.15-rc1**, so by 6.18 the old names **do not +exist**. `from_timer()` → **`timer_container_of()`**: a real mainline rename +(~6.14–6.15 treewide timer-API cleanup; exact tag unconfirmed, verify against +the actual 6.18.46 headers already unpacked at +`flare-edge/research/linux-6.18.46/include/linux/timer.h`). Every call site in +the driver, found by direct grep (not estimated): + +| API | File:line(s) | +|---|---| +| `from_timer()` | `aic8800_bsp/aicsdio.c:1442`; `aic8800_fdrv/aicwf_sdio.c:279,317,2933`; `aic8800_fdrv/rwnx_main.c:1724`; `aic8800_fdrv/rwnx_rx.c:1751,2027` | +| `del_timer_sync()` | `aic8800_bsp/aicsdio.c:1677`; `aic8800_fdrv/aicwf_sdio.c:1048,1054,1297,1303,3152`; `aic8800_fdrv/rwnx_main.c:2181`; `aic8800_fdrv/rwnx_rx.c:1501,1526` | +| `del_timer()` (non-sync) | `aic8800_fdrv/aicwf_tcp_ack.c:108,367,401,462`; `aic8800_fdrv/rwnx_rx.c:1921,2607`; `aic8800_btlpm/aic8800_btlpm.c:580,603,951`; `aic8800_btlpm/lpm.c:558,581,935` | +| `setup_timer()` (pre-4.14 dead branch) | `aic8800_fdrv/aicwf_tcp_ack.c:84` — already `#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)` guarded against a live `timer_setup()` branch; **delete the dead `#if` branch**, don't port it | +| `timer_setup()` calls (unaffected, just listed for completeness) | `aicsdio.c:2059`; `aicwf_sdio.c:3564,3589,3590`; `rwnx_main.c:1841,6118`; `rwnx_rx.c:1433,2510`; `aicwf_tcp_ack.c:87`; both btlpm files:1104/1054 | + +Mechanical fix: sed-rename `from_timer`→`timer_container_of`, `del_timer_sync`→ +`timer_delete_sync`, `del_timer`→`timer_delete` across the ~20 call sites above. +`timer_setup()` itself is unchanged. + +### 3.2 netdev +- **`ndo_do_ioctl` removal (~6.7-era, split into `ndo_eth_ioctl`/`ndo_siocdevprivate` + around 5.14/5.15)**: **already handled** by the vendor. `rwnx_main.c:1457-1474` + already has `#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)` / + `#else .ndo_siocdevprivate = rwnx_do_ioctl,` for both `rwnx_netdev_ops` and + `rwnx_netdev_monitor_ops`. Zero work needed — the guard picks the 6.18-correct + member automatically. **Verify only** that `rwnx_do_ioctl`'s body (line 1368) + still compiles against the `ndo_siocdevprivate` signature + (`int (*)(struct net_device *, struct ifreq *, void __user *, int)` vs the + old ioctl signature) — check on the actual 6.18.46 headers. +- **`netif_rx_ni()` removed (5.18, merged into plain `netif_rx()`, safe from any + context)**: three call sites, **not** version-guarded: `rwnx_rx.c:404,598,1651`. + Mechanical fix: `netif_rx_ni(rx_skb)` → `netif_rx(rx_skb)`. +- **`netif_napi_add()` weight arg dropped (~6.1)**: **not used** anywhere in + this driver (checked, no `netif_napi_add`/NAPI in the tree — the driver does + its own kthread-based RX processing, not NAPI polling). No action. + +### 3.3 cfg80211 — the hard, non-mechanical part +**Verified directly against `flare-edge/research/linux-6.18.46/include/net/cfg80211.h`** +(the actual target tree, not a guess from release notes): +- **`cfg80211_connect_result()`**: **confirmed unchanged and safe.** In 6.18.46 + it's a `static inline` that just forwards to `cfg80211_connect_bss()` + (`cfg80211.h:8654-8661`), with the exact same 8-argument signature the driver + already calls at `rwnx_msg_rx.c:958`. `cfg80211_roamed()` — also **confirmed + unchanged**: 6.18.46 signature is + `cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, gfp_t gfp)` + (`cfg80211.h:8748`), matching the driver's call at `rwnx_msg_rx.c:1006,1010` + (`cfg80211_roamed(dev, &info, GFP_ATOMIC)` against a local + `struct cfg80211_roam_info info`). **No code change required here**; migrating to + `cfg80211_connect_bss()` directly is optional cleanup, not a requirement. +- **`wiphy_new()`/`wiphy_new_nm()`**: **confirmed unchanged.** + `wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)` + (`cfg80211.h:6250-6253`, inline wrapper over `wiphy_new_nm(ops, sizeof_priv, NULL)`) + — matches `rwnx_main.c:5732`'s `wiphy_new(&rwnx_cfg80211_ops, sizeof(struct rwnx_hw))` + exactly. No signature-driven work needed. +- **Wiphy locking overhaul — real, confirmed present, and now precisely scoped + (not a guess).** `cfg80211.h` (~6266, 6325-6362) confirms `wiphy_lock()`/ + `wiphy_unlock()`/`lockdep_assert_wiphy()` and a `struct wiphy_work` deferred-work + mechanism all exist in 6.18.46, and — the load-bearing sentence, directly + from the `wiphy_lock()` doc comment — **"When cfg80211 ops are called, the + wiphy is already locked."** That means: + - The driver's `cfg80211_ops` callbacks themselves (`rwnx_cfg80211_scan`, + `_connect`, `_disconnect`, `_add_key`, `_mgmt_tx`, etc., `rwnx_main.c:5365-5382`) + need **no new locking** — cfg80211 core now takes the wiphy mutex before + calling into any of them, where 5.10-era cfg80211 relied on the caller + holding RTNL instead. + - The real risk is the **other direction**: this driver calls + `cfg80211_scan_done()` / `cfg80211_connect_result()` / `cfg80211_roamed()` + from **firmware-event handling, not from inside an ops callback** — + `rwnx_msg_rx.c` (async, driven by SDIO RX) and `rwnx_main.c:1212,2082,2168` + (also async paths, not the ops entry points). Multiple `cfg80211.h` doc + comments for adjacent notification APIs state "the caller must hold ... + wiphy mutex" (e.g. `cfg80211.h:9428`: "Caller must hold wiphy mutex, + therefore must only be called from sleepable context") — the pattern that + replaced the old "hold RTNL" requirement. **Concretely: every + `cfg80211_*` notification call reached from `rwnx_msg_rx.c` / + the async paths in `rwnx_main.c` needs `wiphy_lock(wiphy)` / + `wiphy_unlock(wiphy)` wrapped around it that wasn't there before** (5.10 + only needed `rtnl_lock()`, which this driver's 3 existing + `rtnl_lock()`/`rtnl_unlock()` sites at `rwnx_main.c:5429/5433, + 6063/6075, 6097/6102` already show it knows how to take defensively — the + fix is adding the wiphy-mutex equivalent at the async notification sites, + not at those 3 sites, which are netdev-registration paths and likely stay + RTNL-only). + - This is still the single highest-effort item in the port — not because the + contract is unknown (it's now confirmed above), but because applying it + correctly means auditing every async→cfg80211 call site in `rwnx_msg_rx.c` + and the async branches of `rwnx_main.c` (1212, 2082, 2168, 2445-2645) one + by one, and because a wrong lock order (wiphy mutex vs. RTNL vs. this + driver's own internal locks/semaphores) produces lockdep splats or + deadlocks that only show up under real traffic, not at compile time. Cross- + check each hunk against how `radxa-pkg/aic8800` (§0) handled the same + transition on its 6.12/6.13 port — it hit this exact wall first. + +### 3.4 SDIO/MMC +No breaking changes found in `sdio_driver`, `sdio_claim_host`/`release_host`, +`sdio_readb`/`writesb`, `sdio_set_block_size` between 5.10 and 6.18 (low +research depth on this axis — treat as low-risk, smoke-test rather than +line-audit). The mainline `dw_mmc`/`dw_mmc-rockchip` host driver is already +proven on 6.18 for eMMC (`../DRIVER-PARITY.md`: `dw_mmc (eMMC) | mainline | ✅ M3`) +and `CONFIG_MMC_DW_ROCKCHIP=y` is already in the live `.config` — the SDIO +*controller* side of this port is de-risked; only the AIC8800 *card driver* +above the `sdmmc` bus is new work. + +### 3.5 proc_ops +`file_operations`→`proc_ops` for procfs landed in **5.6** — already true at the +5.10 baseline this driver was written against, and no further proc_ops changes +were found 5.10→6.18. The three files using `proc_ops`/`proc_create` +(`aicwf_sdio.c`, `aic8800_btlpm.c`, `lpm.c`) should need no change here. + +### 3.6 DMA +No breaking coherent/streaming DMA API changes found 5.10→6.18 relevant to this +driver; SDIO drivers ride MMC-core DMA rather than calling +`dma_alloc_coherent`/`dma_map_single` directly for the card-side data path. +Low risk, not independently line-audited — flag if the build surfaces anything. + +### 3.7 Vendor/Rockchip-only helpers — real mainline gap, not a version delta +`rockchip_wifi_power()` / `rockchip_wifi_set_carddetect()` (declared in +`include/linux/rfkill-wlan.h`, implemented in `net/rfkill/rfkill-wlan.c` in the +**vendor 5.10 tree only** — this is a Rockchip-BSP-vendor subsystem, not +mainline Linux, and does not exist in `flare-edge/research/linux-6.18.46/`). +Call sites: `aic8800_bsp/aicsdio.c:515,517,556,580` and +`aic8800_fdrv/aicwf_sdio.c:1260,1262,1329,1331` (all under +`#ifdef CONFIG_PLATFORM_ROCKCHIP`, which is true for this board). **This is not +a rename — there is nothing to rename to.** Recommended fix: **stub these +calls out entirely** rather than port `rfkill-wlan.c`. The DT already declares +a standard mainline `mmc-pwrseq-simple` (`sdio_pwrseq`, §1) bound via +`mmc-pwrseq = <&sdio_pwrseq>`, which the mainline MMC core already drives at +bus-scan/power-up time through `drivers/mmc/core/pwrseq_simple.c` — a real +mainline mechanism doing the same job (GPIO power/reset sequencing) these +vendor calls were a pre-DT-pwrseq-era stand-in for. `rockchip_wifi_set_carddetect()` +is likewise redundant for a `non-removable` MMC device, which mainline already +auto-rescans. Treat every call site as `#if 0`/deleted, not ported. +`get_cpu_version`/`rockchip_soc_id`-style helpers: **not called anywhere** in +this driver (checked, no hits) — the task's assumption that this driver calls +such a helper does not hold; no action needed. `module_param`, `kthread_run`/ +`kthread_should_stop`: stable, unaffected — used extensively (RX/TX kthreads in +`aicwf_sdio.c`), no changes needed. + +### 3.8 Firmware loading +`request_firmware`/`request_firmware_nowait`/`release_firmware`: stable +5.10→6.18, no signature changes found. Note this driver's actual firmware load +path is `AIC_FW_PATH`-relative direct file read via its own loader +(`aic_load_fw`/`CONFIG_USE_FW_REQUEST` is `?= n` in the Makefile — the vendor +driver does **not** use the standard `request_firmware()` API by default, it +reads firmware files from a configurable path itself). Confirm this stays true +after the port; it's a deliberate vendor choice, not a version-driven gap. + +## 4. File / config / DT port plan + +### 4.1 Files to bring into the 6.18 tree +Copy `aic8800dc/{aic8800_bsp,aic8800_fdrv,aic8800_btlpm}/*.{c,h}` (source only — +exclude every generated `.o`/`.ko`/`.mod.*`/`.cmd`/`Module.symvers`/ +`modules.order` artifact already sitting in the vendor tree from prior +out-of-tree builds) into the 6.18 tree at: +``` +flare-edge/research/linux-6.18.46/drivers/net/wireless/aic8800/ + Kconfig # new: top-level "source" wrapper, see 4.2 + Makefile # obj-y for the 3 subdirs, preserving bsp→fdrv→btlpm link order + aic8800_bsp/ (from aic8800dc/aic8800_bsp/) + aic8800_fdrv/ (from aic8800dc/aic8800_fdrv/, minus usb_host.c/rwnx_pci.*/rwnx_mesh.* — dead + code on this board's SDIO-only, non-mesh config; keep out unless a build + error proves them referenced elsewhere) + aic8800_btlpm/ (from aic8800dc/aic8800_btlpm/) +``` +This is exactly the path the vendor's own `Kconfig` already assumes +(`source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig"`, §1) — no path +rewriting needed inside the sub-Kconfigs. Firmware blobs (§5) go to +`aic8800dc_fw/` under the rootfs firmware path, not into the kernel tree. + +Apply, in this order, on top of the copied source: the `0001` queue_sz clamp +patch, and the Tier-1 SDIO-wakeup-sleep patch (currently only tracked under +`flare-edge/future-features-2/sdk-patches/wifi/patches/0002-aic8800dc-sdio-wakeup-sleep-not-spin.patch` +— pull it from there; it is *not* in this branch's own `sdk-patches/wifi/`, a +separate housekeeping gap worth closing regardless of this port). Then apply +the API-delta fixes from §3. + +### 4.2 Kconfig wiring +Add one line to `flare-edge/research/linux-6.18.46/drivers/net/wireless/Kconfig` +(alongside the existing `source "drivers/net/wireless/broadcom/Kconfig"` etc. +list, `Kconfig:22-38`): +``` +source "drivers/net/wireless/aic8800/Kconfig" +``` +New `drivers/net/wireless/aic8800/Kconfig` — carry the vendor's `aic8800dc/Kconfig` +content forward nearly verbatim (it already has the right shape: an +`AIC_WLAN_SUPPORT` bool gate, an `AIC_FW_PATH` string default, and `source` +lines for the fdrv/btlpm sub-Kconfigs) but change the two `tristate` symbols in +`aic8800_fdrv/Kconfig` (`AIC8800_WLAN_SUPPORT`) and `aic8800_btlpm/Kconfig` +(`AIC8800_BTLPM_SUPPORT`) to **default `y`**, and set `AIC_WLAN_SUPPORT` +default `y` — per the task's requirement, everything built in, not modular, +since the 6.18 rootfs has no working module-loading pipeline yet +(`../PORT-STATUS.md` M3 note: the old 5.10 `.ko`s already fail on 6.18 from +vermagic mismatch, and a rebuilt 6.18 module tree for Buildroot doesn't exist +yet either). + +### 4.3 Config symbols (`=y`, built-in) +``` +CONFIG_WIRELESS=y # already =y in the live 6.18 .config +CONFIG_CFG80211=y # already =y — flipped in "batch2" per ../DRIVER-PARITY.md +CONFIG_WLAN=y # already =y +CONFIG_MMC=y # already =y +CONFIG_MMC_DW_ROCKCHIP=y # already =y +CONFIG_RFKILL=y # already =y +CONFIG_AIC_WLAN_SUPPORT=y # new +CONFIG_AIC8800_WLAN_SUPPORT=y # new +CONFIG_AIC8800_BTLPM_SUPPORT=y # new +CONFIG_BT=y # currently =m in the live .config — flip to =y for the same + # no-working-module-pipeline reason as the aic8800 pieces +CONFIG_BT_HCIUART=y # currently =m — flip alongside CONFIG_BT +CONFIG_BT_HCIUART_H4=y # already =y (H4 is the transport this board's BT actually uses, + # per hardware-86-panel.md: UART1/ttyS1, hciattach -s 1500000 + # ... any 1500000 flow nosleep) +CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_AES=y # driver's + # internal key-handling deps, currently "⬜ batch2" in + # ../DRIVER-PARITY.md — confirm =y, not =m, alongside this work +``` +Do **not** enable `CONFIG_MAC80211` for this driver — confirmed by source +inspection (§3.3 note, no `ieee80211_hw`/mac80211 symbol usage anywhere in +`aic8800_fdrv/`) that this is a pure `cfg80211_ops` full-MAC driver; mac80211 +was only ever needed for the *other* vendor WiFi chips in the shared +`sdk/sysdrv/drv_ko/wifi/` tree (RTL8189FS etc.), not this one. Leaving it out +avoids pulling in a subsystem this port doesn't need. Do **not** carry +`CONFIG_RFKILL_RK` — confirmed unused (`aic8800_btlpm/rfkill.c` calls the +standard mainline `rfkill_register()`, no Rockchip-specific rfkill hook). + +### 4.4 DT changes +On the board DT that M4/M5 work extends +(`warden-sdk/kernel/rv1106-enablement/dts/rv1106-warden.dts` or its successor — +follow the pattern of the M3 `&emmc` addition in `rv1106-warden-m2.dts:126-142`): +1. Port the `sdmmc0_{clk,cmd,bus4,det}` pinctrl group from + `sdk/sysdrv/source/kernel/arch/arm/boot/dts/rv1106-pinctrl.dtsi:700-731` + (not yet in the ported tree — M1–M3 only needed the eMMC/uart2/eth pin + groups). +2. Add the `sdmmc: mmc@ffaa0000` node (clocks `HCLK_SDMMC`/`CCLK_SRC_SDMMC` off + `&cru`, `SCLK_SDMMC_DRV`/`SCLK_SDMMC_SAMPLE` off `&grf_cru` — the same + `grf_cru` dependency the M2 eMMC fix already established, so no new + prerequisite) and the `sdio_pwrseq` node, both transplanted verbatim from + §1's block (interrupt `GIC_SPI 52`, per `rv1106.dtsi:1403-1412` in the + vendor tree). +3. `status = "okay"` on `&sdmmc`, matching the vendor board DT exactly (§1). +4. **Do not** touch `&sdio` (mmc@ff9a0000) — leave `disabled`, it's genuinely + unused hardware on this board (§1 correction). + +### 4.5 Driver init-order note +The 5.10 module load order (`insmod_wifi.sh`, §1) is +`aic8800_bsp → (200ms) → aic8800_fdrv → (2s!) → aic8800_btlpm`, with real sleep +delays between each. Built-in (`=y`), there is no equivalent explicit delay — +initcall order is controlled by link order (the vendor Makefile's `obj-y` list +is already `aic8800_btlpm/ aic8800_fdrv/ aic8800_bsp/` in Makefile-declaration +order but Kbuild links `obj-y` in Makefile order regardless of which appears +first in the `ifeq` block — **preserve `aic8800_bsp` before `aic8800_fdrv` +before `aic8800_btlpm` in the new `drivers/net/wireless/aic8800/Makefile`'s +`obj-y` list**, mirroring the working insmod order) and by each subsystem's +declared `module_init()`/initcall level (all three currently use plain +`module_init()`, which becomes `device_initcall` level when built-in — same +level for all three, so link order is what decides relative sequencing among +them). The observed 2-second gap between `aic8800_bsp` and `aic8800_fdrv` on +the running 5.10 system is suspicious enough (firmware download + chip +bring-up time) that if the built-in probe races ahead of firmware readiness, +watch for it specifically during bring-up (§6) — this is a real risk the +static-link change introduces that modular loading didn't have, not just a +formality. + +## 5. Firmware notes + +Firmware is not open source (binary blobs, as expected for WiFi/BT RF/PHY +patches) but is freely redistributable — no export-control/NDA marking found on +the files themselves or in the vendor tree's licensing. 21 files, +`sdk/sysdrv/drv_ko/wifi/aic8800dc/aic8800dc_fw/` (484 KB total): +``` +aic_userconfig_8800dc.txt, aic_userconfig_8800dw.txt # text config, not firmware +fmacfw_calib_8800dc_{u02,h_u02,hbt_u02}.bin # full-MAC calibration firmware +fmacfw_patch_8800dc_{u02,h_u02,hbt_u02,ipc_u02}.bin # full-MAC patch firmware +fmacfw_patch_tbl_8800dc_{u02,h_u02,hbt_u02,ipc_u02}.bin # patch tables +fw_adid_8800dc_{u02,u02h}.bin # analog/RF ADID cal data +fw_patch_{8800dc_u02,8800dc_u02_ext0,8800dc_u02h}.bin # BT patch firmware +fw_patch_table_8800dc_{u02,u02h}.bin # BT patch tables +lmacfw_rf_8800dc.bin # RF test-mode firmware +``` +Per `aic_bsp_main.c`'s `fw_8800dc_u02[]` table (§1), the exact subset loaded at +runtime depends on `AICBSP_CPMODE_WORK` vs `_TEST` and on `CONFIG_SDIO_BT` +(=n in the vendor Makefile — WiFi and BT firmware are loaded/attached +separately, not as one combo blob, despite the combo chip). **Firmware load +path**: `AIC_FW_PATH` Kconfig default is `/oem/usr/ko/aic8800dc_fw` — this is a +5.10-era Buildroot-rootfs-layout artifact (the `/oem` partition), not a kernel +concept; on the 6.18 rootfs, point this at wherever WardenOS's 6.18 Buildroot +userspace places firmware (likely `/lib/firmware/aic8800dc/` if following +standard mainline convention, or keep `/oem/usr/ko/aic8800dc_fw` if the 6.18 +rootfs partition layout is unchanged from 5.10 — confirm against whatever the +M4/M5 rootfs build actually produces, this is a rootfs-layout decision, not a +kernel one). Not found in `linux-firmware.git` (the mainline firmware +project) — AIC8800 firmware has not been upstreamed there; continue shipping +it the way the vendor tree already does (bundled alongside the driver, loaded +by direct file read per §3.8, not `request_firmware()`). + +**Chip variant**: **AIC8800DC**, confirmed authoritative by the board config +(`RK_ENABLE_WIFI_CHIP=AIC8800DC`) and the SDIO device ID match in source +(`aicsdio.c:75,80`: vendor `0xc8a1`, device `0xc08d`) — not the dual-band +AIC8800D80 seen on other LuckFox boards. 2.4 GHz only in practice (confirmed +on hardware per `wifi-bluetooth-aic8800.md:10`: `iw phy` shows 1 band, 0 +5 GHz channels, despite AIC8800DC being marketed dual-band-capable elsewhere). +"AIC8800DW" appears loosely in some sources for the same part; the board `.mk` +is authoritative. + +## 6. Verify steps + +Follow the existing A/B `_b`-slot hardware-verification loop +(`warden-sdk/kernel/docs/m2-boot-on-c8a3.md`), same method M1–M3 already used: +1. **Build**: driver compiles clean into the 6.18.46 tree (`make ... modules` + is not the target — it's `=y`, so this is just `make zImage`/whatever M2's + `build-m2.sh` wraps, succeeding with the new `drivers/net/wireless/aic8800/` + objects linked into `vmlinux`/the zImage). +2. **Probe**: boot on `warden-c8a3`, confirm in `dmesg`: the `sdmmc` MMC host + binds (`dwmmc_rockchip ffaa0000.mmc: ...`, same pattern M3 already proved + for `ffa90000.mmc`/eMMC), then an SDIO card enumerates on it, then + `aic8800_bsp`'s probe fires (vendor/device ID match, firmware file opens + succeed — watch specifically for `AIC_FW_PATH` resolution failures, §5), + then `aic8800_fdrv` attaches and **`wlan0` appears** in `ip link`. +3. **cfg80211 sanity**: `iw phy` shows the expected single 2.4 GHz band/14 + channels (matching the known-good 5.10 baseline in + `wifi-bluetooth-aic8800.md:10` — a mismatch here is a signal something in + the cfg80211/wiphy port is wrong, not a chip regression). +4. **Scan**: `iw dev wlan0 scan` returns nearby APs — exercises + `rwnx_cfg80211_scan`/`cfg80211_scan_done()` and, indirectly, whether the + wiphy-locking port (§3.3) is functioning rather than deadlocking. +5. **Connect**: associate to a real AP (`wpa_supplicant`/`wpa_cli`, matching + WardenOS's own `wlan0` ownership model — do **not** start `rkwifi_server`, + §1) and confirm `COMPLETED` state plus a DHCP lease — exercises + `rwnx_cfg80211_connect`/`cfg80211_connect_result()`. +6. **Known-regression checks** (carry forward, don't re-discover): confirm the + two hardening patches (§0/§4.1) are actually effective — no console-flood + "cmd timed-out" spam under load, and no CPU-pinning busy-spin if the SDIO + link is stressed (`aicwf_bustx_thr` should sleep, not spin, on a wakeup + failure). Confirm `iw dev wlan0 set power_save off` still behaves as + expected (a wall-powered panel, no reason to want power-save — + `wifi-bluetooth-aic8800.md:41`). +7. **BT** (secondary to WiFi but same milestone): confirm `aic8800_btlpm` + attaches and `hciattach -s 1500000 /dev/ttyS1 any 1500000 flow nosleep` + (the known-good invocation) brings up an HCI device. +8. **Update on landing**: mark the `AIC8800 wifi (bsp/fdrv)` and + `AIC8800 BT (btlpm)` rows in `../DRIVER-PARITY.md` ✅, with the same + "hardware-verified, not just compiled" bar every other row uses. + +## Sources + +- Local (SDK/repo evidence, cited inline above by path:line): + `flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/**`, + `flare-edge/sdk/sysdrv/drv_ko/wifi/Makefile`, + `flare-edge/sdk/sysdrv/source/kernel/arch/arm/boot/dts/{rv1106.dtsi,rv1106-pinctrl.dtsi,rv1106g-luckfox-pico-86panel.dts}`, + `flare-edge/sdk/sysdrv/source/kernel/arch/arm/configs/{rv1106-sdiowifi.config,luckfox_rv1106_linux_defconfig}`, + `flare-edge/*/sdk-patches/wifi/patches/*.patch`, + `flare-edge/research/linux-6.18.46/.config` (live, post-M3, batch2 CFG80211=y), + `flare-edge/research/linux-6.18.46/include/net/cfg80211.h` (directly read to + verify `wiphy_new`, `cfg80211_connect_result`, `wiphy_lock`/`lockdep_assert_wiphy` + against the actual target tree, not release notes — §3.3), + `flare-edge/research/plan44-openwrt/` (checked, no aic8800), + `warden-sdk/kernel/rv1106-enablement/{PORT-STATUS.md,DRIVER-PARITY.md,OVERNIGHT-PLAN.md}`, + `warden-sdk/kernel/docs/{bringup.md,m2-boot-on-c8a3.md}`, + `luckfox-pico-86-panel/{wifi-bluetooth-aic8800.md,hardware-86-panel.md,alternative-bsps.md,sdk-patches.md,boot-chain.md}`. +- Web (via research pass, see §0/§2): github.com/radxa-pkg/aic8800 + + deepwiki.com/radxa-pkg/aic8800; forum.armbian.com topic 50332 ("AIC8800 wifi + sdio module not working with kernel 6.12+"); kernel.org/patchwork commits + `9b13df3fb64e` (timer_delete rename), `2655926aea9b` (netif_rx_ni removal), + `a05829a7222e` (wiphy-lock RTNL migration start); kernelnewbies.org/Linux_6.12; + LKML/lkml.iu.edu mirrors for the timer-rename and wiphy-guard series. + Patchwork/LWN direct fetches were partially blocked by anti-bot walls during + research, so the *exact commit/version* the wiphy-lock migration landed in + is not pinned precisely — but its **presence and current contract in the + actual 6.18.46 tree we're porting to is directly confirmed** (previous + paragraph), which is the fact that actually matters for this port. diff --git a/kernel/rv1106-enablement/wifi/PORT-PROGRESS.md b/kernel/rv1106-enablement/wifi/PORT-PROGRESS.md new file mode 100644 index 0000000..acb7f9e --- /dev/null +++ b/kernel/rv1106-enablement/wifi/PORT-PROGRESS.md @@ -0,0 +1,312 @@ +# AIC8800 wifi+BT port — M5 progress (2026-08-24) + +Status: **DONE — zImage + rv1106-warden.dtb build clean with the driver +built in.** Not flashed/booted (parent session verifies on hardware). + +## Build status + +``` +export PATH=".../sdk/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin:/usr/bin:/bin" +export ARCH=arm CROSS_COMPILE=arm-rockchip830-linux-uclibcgnueabihf- +make ARCH=arm CROSS_COMPILE=$CROSS_COMPILE zImage +make ARCH=arm CROSS_COMPILE=$CROSS_COMPILE rockchip/rv1106-warden.dtb +``` +Clean rebuild (all aic8800 sources touched to force recompilation): **0 +errors**, 104 warnings, all benign vendor-code style (`101 +-Wmissing-prototypes` on internal non-`static` helper functions that were +never prototyped in headers, `3 -Wempty-body` on an existing `if +(...);`-with-no-body debug macro expansion) — none are correctness issues +and none were introduced by version-delta fixes. `zImage is ready`; +`rv1106-warden.dtb` compiles with only the pre-existing, unrelated `&rgb` +graph-endpoint warning (already known from M4 display work, not +wifi-related). Confirmed via `nm vmlinux.unstripped` that the driver is +actually linked in, not silently dropped: `aicbsp_sdio_driver`, +`aicwf_sdio_driver`, `rwnx_cfg80211_ops` all present, and the three +`module_init()`s appear as `device_initcall`s in the correct link order — +`__initcall__kmod_aic8800_fdrv__...rwnx_mod_init` after bsp's init and +`__initcall__kmod_aic8800_btlpm__...aic_bluetooth_mod_init` last. + +## What was copied/wired + +Copied `flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/{aic8800_bsp,aic8800_fdrv, +aic8800_btlpm}/*.{c,h}` into `drivers/net/wireless/aic8800/` in the 6.18 +tree, source-only (excluded `.mod.c`/`.o`/`Module.symvers`/etc build +artifacts left over in the vendor tree from prior out-of-tree builds). + +Dropped as dead code for this board (SDIO-only, no USB/PCIe, `CONFIG_SDIO_BT=n`): +`usb_host.{c,h}`, `rwnx_pci.{c,h}`, `aicwf_usb.c`, `btsdio.c`, `aic_btsdio.c`. + +**One exception the plan flagged correctly**: `rwnx_mesh.{c,h}` was +initially dropped on the same "dead code" theory but had to be **restored** +— `rwnx_tx.c`'s `NL80211_IFTYPE_MESH_POINT` switch-case block is not +preprocessor-gated, so `rwnx_mesh.h`'s types (`struct rwnx_mesh_path`, +`struct rwnx_mesh_proxy`) and prototypes are needed to compile even though +this board never creates a mesh-type interface. Restored both files +(1KB each) and added `rwnx_mesh.o` back to the fdrv `Makefile` object list. +`usb_host.c`/`rwnx_pci.c` did NOT need restoring — no build error ever +referenced them. + +New in-tree Kbuild wiring (not copied from vendor, vendor Makefiles are +out-of-tree `KDIR=` external-module style and don't apply directly): +- `drivers/net/wireless/aic8800/Kconfig` — top-level `AIC_WLAN_SUPPORT` + bool + `AIC_FW_PATH` string, `source`s the fdrv/btlpm sub-Kconfigs. + Wired into `drivers/net/wireless/Kconfig` (new `source` line, alongside + the existing vendor Kconfig list). +- `drivers/net/wireless/aic8800/Makefile` — `obj-y` list preserving + bsp → fdrv → btlpm link order (per PORT-PLAN.md §4.5, since these are + built-in `=y` now and initcall order follows link order). Wired into + `drivers/net/wireless/Makefile` (`obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800/`). +- `aic8800_fdrv/Kconfig`, `aic8800_btlpm/Kconfig` — vendor's `tristate` + symbols changed to `default y` (built-in, not modular; the 6.18 rootfs + has no working module pipeline yet). +- Three new in-tree `Makefile`s (`aic8800_bsp/`, `aic8800_fdrv/`, + `aic8800_btlpm/`) translating the vendor's `ccflags-$(CONFIG_X) += -DX` + pattern into fixed `-D` flags for the one build configuration this board + actually uses (SDIO, Rockchip, no USB/PCI/mesh-in-practice, TCP-ACK + filter, preallocated TXQ, RF test support — see each Makefile's ccflags + for the full list, matching the vendor Makefile defaults). `CONFIG_AIC_FW_PATH` + needs no `-D`: it's now a real Kconfig string symbol, so + `include/generated/autoconf.h` already defines the `CONFIG_AIC_FW_PATH` + C-string macro the driver expects (`aicsdio.c:59`, `aic_bsp_driver.h:348`). + +## API-delta fixes (file → change) + +### Plan-anticipated mechanical renames (applied via scoped `sed`, all call sites) +- `from_timer()` → `timer_container_of()` — 7 sites: `aicsdio.c`, + `aicwf_sdio.c` (×3), `rwnx_main.c`, `rwnx_rx.c` (×2). +- `del_timer_sync()` → `timer_delete_sync()` — 10 sites: `aicsdio.c`, + `aicwf_sdio.c` (×5), `rwnx_main.c` (×2, one more than the plan's count — + `rwnx_main.c:6177` wasn't in the plan's list but grep found it), + `rwnx_rx.c` (×2). +- `del_timer()` → `timer_delete()` — 9 sites: `aicwf_tcp_ack.c` (×4), + `rwnx_rx.c` (×2), `aic8800_btlpm/aic8800_btlpm.c` (×3, dead — not in this + build's object list, fixed anyway for tree hygiene), `aic8800_btlpm/lpm.c` + (×3, same — `lpm.c` isn't compiled, `CONFIG_SUPPORT_LPM=n`). +- `netif_rx_ni()` → `netif_rx()` — 3 sites, all `rwnx_rx.c`. + +### Deltas beyond the plan's list (found by the compiler, fixed against 6.18 headers) +- **`cfg80211_rx_spurious_frame()` / `cfg80211_rx_unexpected_4addr_frame()`** + (`rwnx_rx.c`, 2 sites): gained a `link_id` param before `gfp`; passed + `-1` ("not applicable", per the header's own doc comment — this driver + has no MLO). +- **`cfg80211_ch_switch_notify()` / `cfg80211_ch_switch_started_notify()`** + (`rwnx_main.c`, 2 sites): the vendor's own version-gated compat shim + (`rwnx_compat.h`'s `HIGH_KERNEL_VERSION3`/`4` = 6.3.0) already anticipated + *an* API change here but guessed a 6.3-era signature that's since changed + again by 6.18 (`notify` dropped back to 3 args `(dev, chandef, link_id)`; + `started_notify` is 5 args `(dev, chandef, link_id, count, quiet)`, no + trailing reserved arg). Added a new `#if LINUX_VERSION_CODE >= + KERNEL_VERSION(6, 7, 0)` tier ahead of the existing chain rather than + edit the historical shim; `link_id = 0` (mandatory for non-MLO per the + header). +- **`cfg80211_ops` struct-initializer type mismatches** (`rwnx_main.c`, + 7 callbacks — all gained new params, all effectively "not applicable" for + this single-radio, non-MLO, SDIO full-MAC driver, so the new params are + accepted and ignored): + - `change_beacon`: now takes `struct cfg80211_ap_update *` (wraps the old + `cfg80211_beacon_data` as `.beacon`, plus FILS/S1G/unsol fields unused + here) — unwrapped with `&update->beacon` so `rwnx_build_bcn()` and its + other 3 callers stay untouched. + - `set_monitor_channel`: gained a `struct net_device *dev` param. Rather + than thread an unused `dev` through the well-used internal 2-arg + `rwnx_cfg80211_set_monitor_channel()` (called elsewhere with `chandef = + NULL` to retrieve firmware-level channel state), added a thin + `rwnx_cfg80211_set_monitor_channel_ops()` adapter and pointed the ops + table at that instead. + - `set_wiphy_params`: gained `int radio_idx` before `changed`. + - `set_tx_power`: gained `int radio_idx` between `wdev` and `type`. + - `get_tx_power`: gained `int radio_idx, unsigned int link_id` before the + output pointer. + - `start_radar_detection`: gained a trailing `int link_id`. + - `tdls_mgmt`: gained `int link_id` right after `peer`. +- **`cfg80211_cac_event()`** (`rwnx_radar.c`, 2 sites): gained a trailing + `unsigned int link_id`; passed `0` (mandatory for non-MLO per doc comment). +- **`wakeup_source_create()`/`_add()`/`_remove()`/`_destroy()`** (`rwnx_wakelock.c`): + removed from the public API entirely (still exist internally in + `drivers/base/power/wakeup.c` but are no longer `EXPORT_SYMBOL`'d) — + `wakeup_source_register(dev, name)` / `wakeup_source_unregister(ws)` is + now the only supported entry point (confirmed: `wakeup_source_register()`'s + own implementation is literally `create()` + conditional sysfs + + `add()`). Rewrote `rwnx_wakeup_init()`/`_deinit()` to call + `wakeup_source_register(NULL, name)` / `wakeup_source_unregister(ws)` — + `dev=NULL` registers an anonymous source not tied to a `struct device`, + matching the old `wakeup_source_create()` behavior used here. (The file + already had a correct modern `rwnx_wakeup_register()`/`_unregister()` + pair for a different call path — this fix makes `rwnx_wakeup_init()` + consistent with it.) +- **`MODULE_IMPORT_NS(bare_token)` → `MODULE_IMPORT_NS("string")`** — 3 + sites (`aic_bsp_driver.c`, `rwnx_platform.c`, `rwnx_main.c`), all + importing the same non-mainline `VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver` + namespace token (an Android-GKI-kernel artifact — confirmed absent from + our mainline `fs/` tree, so this is now inert modinfo metadata, not a + real namespace gate). `MODULE_INFO()`/`MODULE_IMPORT_NS()` now require a + quoted string per current `include/linux/module.h`. +- **`rwnx_platform.c`: unconditional `#include "rwnx_pci.h"`** — the header + was dropped with `rwnx_pci.c` (dead code, no PCIe on this board), but this + one `#include` wasn't behind any guard. Guarded it behind + `AICWF_PCIE_SUPPORT` (matching the guard its only two callers, + `rwnx_platform_{,un}register_drv()`, already use at their call sites in + `rwnx_main.c`) and guarded the two functions' `rwnx_pci_{,un}register_drv()` + bodies the same way, returning `0`/no-op for the SDIO-only build instead. +- **`` (vendor-only, PORT-PLAN.md §3.7)** — removed + from 3 files (`aicsdio.c`, `aicwf_sdio.c`, `rwnx_main.c`). Traced every + real `rockchip_wifi_power()`/`_set_carddetect()` call site first: all of + them are either already `#if 0`'d out in the vendor source + (`aicwf_sdio.c`) or gated behind `CONFIG_PLATFORM_ROCKCHIP2` (a symbol + this build never defines — only plain `ROCKCHIP`), so none needed + stubbing individually; only the unconditional header `#include`s needed + removing. The DT's `mmc-pwrseq-simple` node does the power/reset + sequencing instead, as planned. +- **`CONFIG_RFTEST` added to `aic8800_fdrv`'s ccflags** — not itself a + version delta, but needed: `aic_priv_cmd.c`'s RF-test-mode enum + (`SET_TX`, `RDWR_EFUSE_*`, ~50 constants) and struct typedefs + (`cmd_rf_settx_t` etc.) are defined inline in the file under `#ifdef + CONFIG_RFTEST`, and later code in the same file references them + unconditionally. Omitting `-DCONFIG_RFTEST` (as an initial conservative + default) produced ~90 "undeclared identifier" errors; the vendor + Makefile's own default is `CONFIG_RFTEST=y`, so restoring it matches + vendor intent, not a workaround. + +### Duplicate-symbol fixes (the biggest surprise, not in the plan) +The vendor `aic8800_bsp` and `aic8800_fdrv` were always built as two +**independent `.ko` modules**, each with its own private symbol namespace. +Built in-tree as `=y`, both link into one `vmlinux`, and it turns out +`aic8800_bsp` carries a **complete second, self-contained copy** of large +parts of `aic8800_fdrv`'s machinery — its own SDIO byte/frame transport +(`aicwf_sdio_*`, `aicwf_bus_*`, `aicwf_frame_*`, `aicwf_tx_*`, +`aicwf_rx_*`, `crc8_ponl_107`), its own message/debug-command layer +(`rwnx_send_dbg_*_req`, `rwnx_cmd_mgr_{init,deinit}`, +`rwnx_rx_handle_msg`), and a few globals (`chip_mcu_id`, `chip_sub_id`, +`aic_fw_path`, `testmode`) — used for the bsp-side firmware bring-up phase +before fdrv's own driver instance re-probes and takes over the SDIO +function for real runtime operation. **49 symbols total**, `ld` caught +every one as "multiple definition" at the final `vmlinux.o` link (the +per-subdirectory `built-in.a` build had already succeeded — this class of +error only surfaces at the whole-image link, which is worth knowing for +anyone repeating this kind of port). + +Verified via `aic_bsp_export.h` (the real, narrow, intentional +`aicbsp_*`-prefixed bsp→fdrv API surface) that none of the 49 are part of +the actual cross-module contract, and via `grep -rlw` that `fdrv` has its +own **complete** definition of every one (not an `extern` pointing at +bsp's copy) — confirming these are two truly independent implementations, +not one legitimately shared. Fix: renamed all 49 symbols with an +`aicbsp_priv_` prefix, scoped strictly to `aic8800_bsp/*.{c,h}` (both +definitions and bsp-internal call sites via whole-word `sed`); `fdrv`'s +copies are untouched. One of the 49, `md5.c`'s MD5 functions, got a +different (smaller-footprint) fix: `aic8800_bsp/md5.c` and +`aic8800_fdrv/md5.c` are **byte-identical** files, so `md5.o` was simply +dropped from `aic8800_fdrv`'s object list instead of renamed — `fdrv`'s +calls resolve against `bsp`'s copy at link time since bsp links first. + +## Config symbols set + +``` +CONFIG_AIC_WLAN_SUPPORT=y +CONFIG_AIC8800_WLAN_SUPPORT=y +CONFIG_AIC8800_BTLPM_SUPPORT=y +CONFIG_AIC_FW_PATH="/oem/usr/ko/aic8800dc_fw" +CONFIG_WIRELESS=y CONFIG_CFG80211=y CONFIG_WLAN=y (already y pre-port) +CONFIG_MMC=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_RFKILL=y (already y pre-port) +CONFIG_BT=y (was =m, flipped to =y — no module pipeline yet) +CONFIG_BT_HCIUART=y (was =m, flipped to =y) +CONFIG_BT_HCIUART_H4=y (already y) +CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_AES=y +# CONFIG_MAC80211 is not set (explicitly left off — pure cfg80211 full-MAC + driver, confirmed no mac80211/ieee80211_hw + symbol usage anywhere in aic8800_fdrv) +``` +Ran `olddefconfig` after setting these; verified afterward that other +ported drivers' symbols (`CONFIG_CLK_RV1106`, `CONFIG_PINCTRL_ROCKCHIP`, +`CONFIG_DRM_ROCKCHIP`, `CONFIG_MMC_DW_ROCKCHIP`) are untouched. + +## Device tree + +`arch/arm/boot/dts/rockchip/rv1106-warden.dts`: +- New root-level `sdio_pwrseq: sdio-pwrseq` node (`mmc-pwrseq-simple`, + `reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>`), transplanted verbatim + from the vendor board DTS. +- New `&sdmmc` override: `max-frequency = <50000000>`, `bus-width = <4>`, + `cap-sd-highspeed`, `cap-sdio-irq`, `keep-power-in-suspend`, + `non-removable`, `rockchip,default-sample-phase = <90>`, + `supports-sdio`, `mmc-pwrseq = <&sdio_pwrseq>`, pinctrl + `sdmmc0_clk`/`_cmd`/`_bus4`/`_det`, `status = "okay"`. +- `&sdio` (mmc@ff9a0000) left untouched — stays `disabled`, genuinely + unused hardware on this board. + +**Note**: the `&sdmmc` node itself (`mmc@ffaa0000`) in `rv1106.dtsi` and +the `sdmmc0_*` pinctrl groups in `rv1106-pinctrl.dtsi` were **already +present** in this tree from earlier M1–M3 work (not added by this task) — +this task only added the board-DTS *enablement* (`status = "okay"` + +properties) and the new `sdio_pwrseq` node. Verified in the compiled +`.dtb` (decompiled with `dtc -I dtb -O dts`) that both nodes carry the +correct phandles/properties. + +## Hardening patches + +Both hardware-verified patches from the plan are **already present in the +vendor SDK source** we copied from (not merely trackable-but-unapplied) — +confirmed two ways: `patch -p5 --dry-run` on both reported "Reversed (or +previously applied) patch detected" against the freshly-copied tree, and +`grep` found their exact markers already in place: +- `0001-aic8800dc-no-zero-timeout-spin-and-ratelimit.patch` + (`major-app-additions/sdk-patches/wifi/patches/`): `printk_ratelimited` + and the `max_t(u32, cmd_mgr->queue_sz, 1)` clamp are both in + `rwnx_cmds.c` as shipped. + `future-features-2/sdk-patches/wifi/patches/0002-aic8800dc-sdio-wakeup-sleep-not-spin.patch`: +- `usleep_range(200, 400)`, the `woke` flag, and the "SDIO wakeup failed; + chip may be wedged" message are all in `aicwf_sdio.c` as shipped. + +No action needed beyond copying the source. **Known housekeeping gap +(pre-existing, not fixed by this task, flagged by the plan)**: patch 0002 +is still only tracked under `future-features-2/sdk-patches/wifi/patches/`, +not this branch's own `sdk-patches/wifi/patches/` — worth closing +separately since the fix is live in the vendor tree either way. + +## Constraints honored + +Only touched: the wifi driver tree (`drivers/net/wireless/aic8800/`), its +Kconfig/Makefile wiring (`drivers/net/wireless/{Kconfig,Makefile}`), the +board DTS wifi nodes (`rv1106-warden.dts`, additive only), and +wifi/BT/crypto-related `.config` symbols. Did not touch any other driver, +DT node, or unrelated config symbol — spot-checked after the port that +`CONFIG_CLK_RV1106`, `CONFIG_PINCTRL_ROCKCHIP`, `CONFIG_DRM_ROCKCHIP`, +`CONFIG_MMC_DW_ROCKCHIP` are all still `=y`, and the `&rgb`/VOP-related dtc +warning is the same pre-existing one from M4 (not new). Never touched +hardware — no kflash, no reboot, no `/dev/ttyUSB2`, no Pi. + +## What the parent should watch for on hardware + +Per PORT-PLAN.md §6's verify sequence: +1. `dmesg`: `dwmmc_rockchip ffaa0000.mmc: ...` binding (mirrors the M3 + eMMC pattern on `ffa90000.mmc`), then an SDIO card enumerating on it + (vendor/device ID `0xc8a1`/`0xc08d`), then `aic8800_bsp`'s probe firing. +2. **Firmware path**: `AIC_FW_PATH` defaults to `/oem/usr/ko/aic8800dc_fw` + — a 5.10-era Buildroot `/oem` partition path. Confirm the 6.18 rootfs + actually has firmware there (or update `CONFIG_AIC_FW_PATH` to wherever + it landed) — watch specifically for firmware-open failures in dmesg as + the first failure mode, before assuming a driver/DT bug. +3. `wlan0` should appear in `ip link` once `aic8800_fdrv` attaches. +4. `iw phy` should show one 2.4 GHz band, 14 channels (matches the known + 5.10 baseline — a mismatch signals a cfg80211/wiphy port bug, not a + chip issue). +5. `iw dev wlan0 scan` and a real AP association exercise the + wiphy-locking behavior (§3.3 of the plan) — this is the area with the + least direct verification in this port (the driver's own ops callbacks + need no new locking per the plan's analysis, since cfg80211 core now + holds the wiphy mutex before calling in; the async-context notification + calls from `rwnx_msg_rx.c` were flagged as the highest-residual-risk + area and were NOT touched by this build-fix pass beyond the signature + changes above — if scan/connect hang or lockdep splats appear, look + there first). +6. Confirm the two hardening patches are actually effective under load: no + "cmd timed-out" console flood, no CPU-pinning busy-spin on a stressed/ + wedged SDIO link (`aicwf_bustx_thr` should sleep, not spin). +7. BT: `aic8800_btlpm` should attach; `hciattach -s 1500000 /dev/ttyS1 any + 1500000 flow nosleep` should bring up an HCI device. +8. Given the scale of the bsp/fdrv duplicate-symbol rename (49 symbols), + if anything behaves subtly wrong in the bsp-side firmware bring-up + phase specifically (vs. fdrv's runtime path), double-check the rename + didn't miss a cross-file reference within `aic8800_bsp/` — it was done + with whole-word `sed` scoped to that directory and re-verified by a + clean rebuild, but it touched every `.c`/`.h` in that subtree. diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/Kconfig b/kernel/rv1106-enablement/wifi/kbuild/aic8800/Kconfig new file mode 100644 index 0000000..9e37be9 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/Kconfig @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# AICSemi AIC8800DC SDIO WiFi+BT driver (WardenOS M5 port). +# +# Ported from the vendor 5.10.160 out-of-tree source +# (flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/) — see +# warden-sdk/kernel/rv1106-enablement/wifi/PORT-PLAN.md and PORT-PROGRESS.md. +# Built-in only (=y): the 6.18 rootfs has no working module-loading pipeline +# yet, so these default to y rather than the vendor's default-n/tristate. + +config AIC_WLAN_SUPPORT + bool "AIC wireless Support" + default y + help + This is support for the AIC wireless chip (AIC8800DC SDIO combo + wifi+BT on the WardenOS 86-Panel). + +config AIC_FW_PATH + depends on AIC_WLAN_SUPPORT + string "Firmware & config file path" + default "/oem/usr/ko/aic8800dc_fw" + help + Path to the firmware & config files. The driver reads these + directly (not via request_firmware()) — see PORT-PLAN.md §3.8. + +if AIC_WLAN_SUPPORT +source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig" +source "drivers/net/wireless/aic8800/aic8800_btlpm/Kconfig" +endif diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/Makefile b/kernel/rv1106-enablement/wifi/kbuild/aic8800/Makefile new file mode 100644 index 0000000..b7432c6 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Link order matters: bsp before fdrv before btlpm, mirroring the working +# insmod order (insmod_wifi.sh) now that these are built-in (=y) instead of +# modules — see PORT-PLAN.md §4.5. +obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/ +obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/ +obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/ diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_bsp/Makefile b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_bsp/Makefile new file mode 100755 index 0000000..64f8480 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_bsp/Makefile @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# aic8800_bsp — SDIO bus glue + firmware bootstrap, ported in-tree from the +# vendor out-of-tree Makefile (flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/ +# aic8800_bsp/Makefile). CONFIG_AIC_FW_PATH is now a real Kconfig string +# symbol (see ../Kconfig) so it needs no -D here — the driver picks it up +# from include/generated/autoconf.h directly (aicsdio.c, aic_bsp_driver.h). +# +# Vendor CONFIG_* build-time knobs below are preserved as fixed -D flags +# (not full Kconfig symbols) since this port only needs the one build +# configuration this board actually uses (SDIO, Rockchip, no USB/PCI/mesh). + +ccflags-y += -DAICWF_SDIO_SUPPORT +ccflags-y += -DCONFIG_SDIO_PWRCTRL +ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP +ccflags-y += -DCONFIG_LINK_DET_5G +ccflags-y += -DCONFIG_VRF_DCDC_MODE +ccflags-y += -DCONFIG_PREALLOC_TXQ +ccflags-y += -DCONFIG_DPD -DCONFIG_FORCE_DPD_CALIB +ccflags-y += -DCONFIG_RESV_MEM_SUPPORT +ccflags-y += -DCONFIG_AMSDU_RX +ccflags-y += -Wno-unused-function + +obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp.o +aic8800_bsp-y := \ + aic8800dc_compat.o \ + aic8800d80_compat.o \ + aic_bsp_main.o \ + aic_bsp_driver.o \ + aicsdio.o \ + aicsdio_txrxif.o \ + md5.o \ + aicwf_txq_prealloc.o diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_btlpm/Kconfig b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_btlpm/Kconfig new file mode 100755 index 0000000..872a606 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_btlpm/Kconfig @@ -0,0 +1,7 @@ +config AIC8800_BTLPM_SUPPORT + tristate "AIC8800 bluetooth Support" + default y + help + This is support for the aic8800 bluetooth low-power-mode / HCI + wake companion module (aic8800_btlpm). Built-in (y) by default — + see the aic8800 port notes in warden-sdk/kernel/rv1106-enablement/wifi/. diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_btlpm/Makefile b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_btlpm/Makefile new file mode 100755 index 0000000..21750dd --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_btlpm/Makefile @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# aic8800_btlpm — Bluetooth low-power-mode / HCI wake companion module, +# ported in-tree from the vendor out-of-tree Makefile +# (flare-edge/sdk/sysdrv/drv_ko/wifi/aic8800dc/aic8800_btlpm/Makefile). +# lpm.c stays out of the build (CONFIG_SUPPORT_LPM was already off in the +# vendor default; aic8800_btlpm.c's own has_lpm_enabled/lpm_fops logic is +# self-contained and does not call into lpm.c). + +ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP +ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp + +obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm.o +aic8800_btlpm-y := \ + aic_bluetooth_main.o \ + rfkill.o diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_fdrv/Kconfig b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_fdrv/Kconfig new file mode 100755 index 0000000..33728e7 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_fdrv/Kconfig @@ -0,0 +1,7 @@ +config AIC8800_WLAN_SUPPORT + tristate "AIC8800 wlan Support" + default y + help + This is support for the aic8800 cfg80211 full-MAC wifi driver + (aic8800_fdrv). Built-in (y) by default — see the aic8800 port + notes in warden-sdk/kernel/rv1106-enablement/wifi/. diff --git a/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_fdrv/Makefile b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_fdrv/Makefile new file mode 100755 index 0000000..8c0ba85 --- /dev/null +++ b/kernel/rv1106-enablement/wifi/kbuild/aic8800/aic8800_fdrv/Makefile @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# aic8800_fdrv — the cfg80211 full-MAC driver ("fdrv"), ported in-tree from +# the vendor out-of-tree Makefile (flare-edge/sdk/sysdrv/drv_ko/wifi/ +# aic8800dc/aic8800_fdrv/Makefile). SDIO-only build (this board has no +# USB/PCI variant) — usb_host.c and rwnx_pci.c are dropped from the tree +# entirely (PORT-PLAN.md §4.1 flagged both as candidates to drop "unless a +# build error proves them referenced elsewhere" — that held for these two). +# rwnx_mesh.c was ALSO dropped initially on the same theory but had to be +# restored: rwnx_tx.c's NL80211_IFTYPE_MESH_POINT switch-case is not +# preprocessor-gated, so rwnx_mesh.h's types/prototypes are needed to +# compile even though this board never creates a mesh-type interface. +# md5.o is dropped from THIS module's object list only: it is byte-identical +# to aic8800_bsp's +# md5.c (same non-static MD5Init/MD5Update/... symbols) and, unlike the +# old separate .ko world, both drivers now link into one vmlinux — keeping +# both objects would be a multiple-definition link error. aic8800_bsp +# links first (../Makefile) so fdrv's calls resolve against its md5.o. + +ccflags-y += -DCONFIG_RWNX_FULLMAC +ccflags-y += -DAICWF_SDIO_SUPPORT +ccflags-y += -DCONFIG_SDIO_PWRCTRL +ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP +ccflags-y += -DCONFIG_START_FROM_BOOTROM +ccflags-y += -DCONFIG_PMIC_SETTING +ccflags-y += -DCONFIG_VRF_DCDC_MODE +ccflags-y += -DCONFIG_ROM_PATCH_EN +ccflags-y += -DCONFIG_RWNX_RADAR +ccflags-y += -DCONFIG_RWNX_BCMC +ccflags-y += -DNX_TXQ_CNT=5 +ccflags-y += -DCONFIG_USER_MAX=1 +ccflags-y += -DCONFIG_RWNX_DBG +ccflags-y += -DUSE_5G +ccflags-y += -DCONFIG_TXRX_THREAD_PRIO +ccflags-y += -DCONFIG_SUPPORT_REALTIME_CHANGE_MAC +ccflags-y += -DCONFIG_PREALLOC_TXQ +ccflags-y += -DCONFIG_DPD -DCONFIG_FORCE_DPD_CALIB +ccflags-y += -DCONFIG_FILTER_TCP_ACK +ccflags-y += -DCONFIG_RESV_MEM_SUPPORT +ccflags-y += -DCONFIG_SHUTDOWN_CALLBACK +ccflags-y += -DCONFIG_MCC +ccflags-y += -DCONFIG_RFTEST +ccflags-y += -DCONFIG_RX_NETIF_RECV_SKB +ccflags-y += -DAICWF_RX_REORDER +ccflags-y += -DAICWF_ARP_OFFLOAD + +# FW/IPC sizing (vendor 8800DCDW u02 variant) +ccflags-y += -DNX_VIRT_DEV_MAX=4 +ccflags-y += -DNX_REMOTE_STA_MAX_FOR_OLD_IC=10 +ccflags-y += -DNX_REMOTE_STA_MAX=32 +ccflags-y += -DNX_MU_GROUP_MAX=62 +ccflags-y += -DNX_TXDESC_CNT=64 +ccflags-y += -DNX_TX_MAX_RATES=4 +ccflags-y += -DNX_CHAN_CTXT_CNT=3 +ccflags-y += -DDEFAULT_COUNTRY_CODE=\"00\" +ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src) + +ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp +ccflags-y += -Wno-implicit-fallthrough -Wno-unused-function -Wno-unused-variable + +obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv.o +aic8800_fdrv-y := \ + rwnx_msg_tx.o \ + rwnx_msg_rx.o \ + rwnx_utils.o \ + rwnx_cmds.o \ + rwnx_irqs.o \ + rwnx_cfgfile.o \ + rwnx_strs.o \ + rwnx_rx.o \ + rwnx_tx.o \ + rwnx_txq.o \ + rwnx_main.o \ + rwnx_mod_params.o \ + rwnx_mesh.o \ + rwnx_platform.o \ + rwnx_dini.o \ + rwnx_v7.o \ + ipc_host.o \ + rwnx_tdls.o \ + aic_vendor.o \ + aicwf_compat_8800dc.o \ + aicwf_compat_8800d80.o \ + rwnx_wakelock.o \ + regdb.o \ + aic_priv_cmd.o \ + aicwf_rx_prealloc.o \ + rwnx_radar.o \ + sdio_host.o \ + aicwf_txrxif.o \ + aicwf_sdio.o \ + aicwf_tcp_ack.o diff --git a/kernel/rv1106-enablement/wifi/wifi-dt-block.dtsi b/kernel/rv1106-enablement/wifi/wifi-dt-block.dtsi new file mode 100644 index 0000000..09b4d2e --- /dev/null +++ b/kernel/rv1106-enablement/wifi/wifi-dt-block.dtsi @@ -0,0 +1,40 @@ + /* --- M5: AIC8800DC wifi/BT power sequencing --- */ + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + }; +}; + +/* --- console --- */ +&uart2 { + status = "okay"; +}; + +/* --- eMMC rootfs (M3) --- */ +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +/* --- M5: AIC8800DC wifi/BT SDIO (on &sdmmc, mmc@ffaa0000 — NOT &sdio) --- */ +&sdmmc { + max-frequency = <50000000>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + non-removable; + rockchip,default-sample-phase = <90>; + supports-sdio; + mmc-pwrseq = <&sdio_pwrseq>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>; + status = "okay"; +}; + +/* --- batch 1: mainline peripherals (wire DT + config) --- */ +&uart1 {