5.2 KiB
FreeBSD 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:
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:
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-*.candpatches/patch-Makefile). Safe to re-run.build.sh— buildsif_bwn.ko(sys/modules/bwn),bhndb_pci.ko(sys/modules/bhnd/bhndb_pci), andbwn_v4_n.ko(fromsrc/firmware/); installs them to/boot/modulesand/boot/kernel; and appendsbwn_v4_n_load="YES"to/boot/loader.confif missing (Fix 5).
Manual build (equivalent to build.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:
- The GPL N-PHY code is not compiled in (build wiring).
- A NULL ring pointer can be dereferenced on a partial attach.
- Multicast updates are not wired to
ic->ic_update_mcast. - Firmware is not found at attach (loader vs kld_list ordering).
- MSI interrupts are never delivered on this host (NVIDIA MCP89 bridge), so TX completions never run -> "device timeout" and the NIC never passes traffic.
- Detaching while a TX frame is pending double-frees an
ieee80211_node(kernel panic). - 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.csys/modules/bwn/Makefilesys/dev/bhnd/bhndb/bhndb_pci.csys/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.
Credits
Created by Luxferre in 2026, released into the public domain with no warranties.