Patches + build scripts + firmware sources to make the Broadcom BCM43224
(PCI 0x14e4:0x4353, subvendor 0x106b:0x00d1) work on FreeBSD 15.1.
Fixes:
- Fix 1: compile GPL N-PHY code (BWN_GPL_PHY build wiring)
- Fix 2: NULL-guard bwn_dma_ringfree on partial attach
- Fix 3: wire bwn_update_mcast to ic->ic_update_mcast
- Fix 5: load bwn_v4_n firmware at loader stage (loader.conf)
- Fix 6: reclaim pending TX frames at bwn_dma_stop (detach double-free)
- Fix 7: driver-owned node ref + remove dr_usedslot early-return +
bhndb_pci BHNDB_PCI_QUIRK_NO_MSI for BCM43224 (legacy INTx)
- Fix 8: restrict reclaim to TX rings only (RX reclaim caused heap
corruption / TCP panic)
README.md = rebuild guide (apply.sh + build.sh, manual steps)
RESEARCH.md = root-cause investigation log (Fixes 5-8)
121 lines
5.1 KiB
Markdown
121 lines
5.1 KiB
Markdown
# bwn driver fixes for Broadcom BCM43224 (Apple MacBook Air A1370)
|
|
|
|
A complete, self-contained set of fixes that make the FreeBSD `bwn(4)` driver
|
|
work on the Apple MacBook Air A1370's BCM43224
|
|
(PCI `0x14e4:0x4353`, subvendor `0x106b:0x00d1`) 802.11a/b/g/n chip.
|
|
|
|
The driver has been tested through multiple `kldunload`/`kldload` cycles and
|
|
reboots on the target hardware with no panic.
|
|
|
|
## Build & install (clean FreeBSD 15.1)
|
|
|
|
You need the FreeBSD 15.1 **source tree** at `/usr/src` (or pass an alternate
|
|
`SRC_ROOT` to the scripts). Then, as root:
|
|
|
|
```sh
|
|
cd bwn-a1370
|
|
sudo ./apply.sh # patch /usr/src (or: sudo ./apply.sh /path/to/src)
|
|
sudo ./build.sh # build + install if_bwn.ko, bhndb_pci.ko, bwn_v4_n.ko
|
|
reboot
|
|
```
|
|
|
|
After reboot, bring up the interface:
|
|
|
|
```sh
|
|
ifconfig wlan create wlandev bwn0 [wap]
|
|
# or, to join a WPA network, create the wlan and run wpa_supplicant as usual
|
|
```
|
|
|
|
`build.sh` installs everything for the **next boot**; it does not touch the
|
|
running kernel, so an active session (e.g. SSH over a fallback `rtwn0/wlan0`
|
|
interface) is never disrupted.
|
|
|
|
### What the scripts do
|
|
|
|
- `apply.sh` — idempotently applies the 4 source patches to `/usr/src`
|
|
(`patches/patch-*.c` and `patches/patch-Makefile`). Safe to re-run.
|
|
- `build.sh` — builds `if_bwn.ko` (`sys/modules/bwn`), `bhndb_pci.ko`
|
|
(`sys/modules/bhnd/bhndb_pci`), and `bwn_v4_n.ko` (from `src/firmware/`);
|
|
installs them to `/boot/modules` and `/boot/kernel`; and appends
|
|
`bwn_v4_n_load="YES"` to `/boot/loader.conf` if missing (Fix 5).
|
|
|
|
### Manual build (equivalent to build.sh)
|
|
|
|
```sh
|
|
SRC=/usr/src
|
|
|
|
# 1. driver
|
|
make -C $SRC/sys/modules/bwn SRCTOP=$SRC SYSDIR=$SRC/sys
|
|
install -m 444 $SRC/sys/modules/bwn/if_bwn.ko /boot/modules/
|
|
|
|
# 2. PCIe bridge (NO_MSI quirk)
|
|
make -C $SRC/sys/modules/bhnd/bhndb_pci SRCTOP=$SRC SYSDIR=$SRC/sys
|
|
install -m 444 $SRC/sys/modules/bhnd/bhndb_pci/bhndb_pci.ko /boot/kernel/
|
|
|
|
# 3. firmware
|
|
make -C src/firmware SRCTOP=$SRC SYSDIR=$SRC/sys
|
|
install -m 444 src/firmware/bwn_v4_n.ko /boot/modules/
|
|
|
|
# 4. loader.conf (Fix 5)
|
|
echo 'bwn_v4_n_load="YES"' >> /boot/loader.conf
|
|
```
|
|
|
|
## Directory layout
|
|
|
|
```
|
|
bwn-a1370/
|
|
README.md This file (rebuild guide)
|
|
RESEARCH.md Root-cause investigation log (Fixes 5-8)
|
|
apply.sh Apply the 4 source patches to /usr/src (idempotent)
|
|
build.sh Build + install all 3 modules and add the loader.conf entry
|
|
loader.conf.bwn Snippet for /boot/loader.conf (Fix 5: load firmware at boot)
|
|
patches/
|
|
patch-if_bwn.c Driver fixes (Fixes 1-4, 6-8)
|
|
patch-Makefile GPL PHY build wiring (Fix 1)
|
|
patch-bhndb_pci.c NO_MSI quirk for BCM43224 (Fix 7)
|
|
patch-bhndb_pcivar.h NO_MSI quirk definition (Fix 7)
|
|
combined.patch All of the above in one file (alternative to apply.sh)
|
|
src/firmware/ Broadcom v4 firmware module (bwn_v4_n.ko) sources + Makefile
|
|
rc.conf.backups/ Backups of loader.conf/rc.conf made by the scripts
|
|
```
|
|
|
|
## What was broken (summary)
|
|
|
|
On a stock FreeBSD 15.1 system this chip (an N-PHY rev-23 core behind a
|
|
BCMA/bhnd bus, attached via the `bhndb_pci` PCIe-G1 bridge) failed in several
|
|
ways:
|
|
|
|
1. The GPL N-PHY code is not compiled in (build wiring).
|
|
2. A NULL ring pointer can be dereferenced on a partial attach.
|
|
3. Multicast updates are not wired to `ic->ic_update_mcast`.
|
|
4. Firmware is not found at attach (loader vs kld_list ordering).
|
|
5. **MSI interrupts are never delivered** on this host (NVIDIA MCP89 bridge),
|
|
so TX completions never run -> "device timeout" and the NIC never passes
|
|
traffic.
|
|
6. Detaching while a TX frame is pending double-frees an `ieee80211_node`
|
|
(kernel panic).
|
|
7. Reclaiming the **RX** ring at device-stop DMAs received frames into freed
|
|
kernel memory -> heap corruption / TCP panic.
|
|
|
|
| # | Area | Problem | Fix |
|
|
|---|------|---------|-----|
|
|
| 1 | build | GPL N-PHY code not compiled in | `BWN_GPL_PHY` via `opt_bwn.h`; add 7 GPL PHY files to `SRCS` in `modules/bwn/Makefile` |
|
|
| 2 | `bwn_dma_ringfree` | NULL ring deref on partial attach | NULL-guard `if (dr == NULL \|\| *dr == NULL) return;` |
|
|
| 3 | `bwn_update_mcast` | mcast not updated | wire to `ic->ic_update_mcast` |
|
|
| 4 | `build.sh` | reload clobbered live iface | unload/rebuild/reinstall/reload `if_bwn` only |
|
|
| 5 | `/boot/loader.conf` | firmware not found at attach | `bwn_v4_n_load="YES"` loads firmware at loader stage |
|
|
| 6 | `bwn_dma_stop` | detach double-frees node (vmcore.4) | reclaim pending TX frames (drop node refs) at device-stop |
|
|
| 7 | `if_bwn` + `bhndb_pci` | node ref ownership + MSI never delivered (vmcore.5 / "device timeout") | driver takes its own `ieee80211_ref_node()`; remove `dr_usedslot` early-return; `BHNDB_PCI_QUIRK_NO_MSI` for BCM43224 forces legacy INTx |
|
|
| 8 | `bwn_dma_stop` | RX-ring reclaim -> heap corruption (vmcore.6) | restrict reclaim to TX rings only (new `bwn_dma_reclaim_tx()`) |
|
|
|
|
## Files modified in /usr/src
|
|
|
|
- `sys/dev/bwn/if_bwn.c`
|
|
- `sys/modules/bwn/Makefile`
|
|
- `sys/dev/bhnd/bhndb/bhndb_pci.c`
|
|
- `sys/dev/bhnd/bhndb/bhndb_pcivar.h`
|
|
|
|
(Plus the prebuilt `bwn_v4_n.ko` firmware, reproducible from `src/firmware/`.)
|
|
|
|
See `RESEARCH.md` for the full root-cause analysis behind each fix.
|