Eight percent packet loss, a kernel panic, and the €15 answer that was hiding in plain sight
The morning after Frankie came alive, I wrote a backup script.
A hundred lines of bash that would SSH into the Oracle VM, check that PostgreSQL was healthy, check that disk space was above 5 GB, check that load was below 4.0. If everything passed, it would pull a pg_dump, gzip it, and store it on Frankie's 120 GB disk. Two dumps kept. Everything older deleted. A safeguard, not an archive. Geographic redundancy: the VM in Frankfurt, Frankie on Kefalonia. The job would run at 04:00, when the island sleeps and the WiFi air is quiet.
I finished the script at 23:00. I ran one test before bed.
ping -c 100 8.8.8.8
Sixty percent loss.
That was from across the room. I moved Frankie next to the router. Eighty-eight percent signal. Two hundred seventy megabits per second negotiated rate. Locked to 2.4 GHz, powersave disabled.
ping -c 100 8.8.8.8
Nine percent loss.
The b43 driver, the open-source driver for the Broadcom BCM4321, has a hard ceiling. I spent the next three hours proving it.
The ceiling
The internet is full of tuning advice for b43. Disable powersave. Lock to 2.4 GHz. Force legacy rates with iw. Add module options. I did all of it.
I disabled powersave in NetworkManager. I locked the connection to 802.11b/g with nmcli. I installed iw and forced legacy-2.4 bitrates. I moved the machine until it was touching the router. The signal indicator showed full bars. The negotiated rate showed 270 Mbit/s, a figure that is impossible on 2.4 GHz channel 1 with 20 MHz width, which means the router was using 40 MHz channel bonding, a mode b43 handles badly.
I forced 20 MHz width. I forced lower rates. I added options b43 nohwcrypt=1 qos=0 to /etc/modprobe.d/b43.conf.
ping -c 100 8.8.8.8
Nine percent loss. Round-trip times spiking to 86 milliseconds. The driver was not failing because of configuration. The driver was failing because it is the driver. The b43 codebase for the BCM4321 rev 05 has a ceiling, and that ceiling is 8 to 10 percent packet loss at full signal.
This is not a signal problem. This is a driver problem.
The escape hatch that was not
Every forum thread about the BCM4321 ends the same way. "Just use the proprietary wl driver." I tried.
I installed bcmwl-kernel-source. I blacklisted b43, bcma, ssb. I rebooted.
The kernel panicked. dmesg showed wl_module_init call stacks. The wl driver crashes on init with this kernel, on this hardware, after the 193-package upgrade that fixed everything else. The upgrade that brought b43 to life did not make wl viable. They are mutually exclusive on this machine, and wl loses.
I reverted. Removed the blacklist, reloaded b43, reconnected. Nine percent loss. But at least it connected.
What nine percent means
Nine percent packet loss does not matter for browsing. Falkon retries. Pages load. It does not matter for SSH: type a command, if a packet drops, the terminal hangs for half a second, then recovers. It does not matter for writing this article in Geany, which is entirely offline.
But nine percent matters for an unattended 04:00 backup job pulling a multi-gigabyte PostgreSQL dump over SSH. A dropped packet in the middle of an scp does not recover cleanly. The transfer hangs. The cron job fails. The safeguard is not safe. A backup that fails silently is worse than no backup, because it gives you false confidence.
I tested this. I ran the script manually. It failed twice in three attempts. The third attempt completed, but the transfer took fourteen minutes for a 1.2 GB dump because TCP was constantly retransmitting. Over a wired connection, the same transfer would take four minutes.
Frankie could not be a server over WiFi. Not because the WiFi was weak, but because the driver was honest about its limits.
The €15 answer
A USB Ethernet adapter costs €15. Any USB 2.0 to RJ45 adapter works on Linux without drivers. Plug it in, the kernel sees eth0, DHCP fires, ping shows zero percent loss. The backup script works. The cron job works. Frankie becomes the server it was meant to be.
I do not have the adapter yet. On the island, it might take a week to find one. Until then, Frankie is in limbo. The script is written. The cron is ready. The machine waits.
The pivot
If Frankie cannot come to the work over WiFi, and the adapter is not here yet, then Frankie's role must change. I stripped the server plan. No headless conversion. No 04:00 cron. No Tailscale tunnel. Frankie stays in the GUI, running LXQt, waiting.
The options without the adapter are real but limited. Frankie can be a learning sandbox: break it, reinstall it, try Arch, try Ansible, try Docker. The WiFi flakiness does not matter because the work is local. Frankie can be a distraction-free writing machine: Geany, Vim, Markdown, no browser, no notifications. Frankie can babysit an Arduino or an ESP32 over USB. The machine does not need internet; it needs a serial port and a screen.
But none of these are what Frankie was meant to be. Frankie was meant to be a server. A backup anchor. A quiet machine in the corner that pulls a dump while I sleep.
That future costs €15. Not €1,500 for a new laptop. Not €500 for a used ThinkPad. €15 for a USB Ethernet adapter that removes the wireless variable entirely.
Sometimes the cheapest solution is the one you pay for.
The infrastructure, right now:
Local dev: Frankie, 2008 MacBook Air, Lubuntu, LXQt, no GPU acceleration,
b43WiFi with 9% loss,mbpfantuned to 55/60Production database: Oracle Cloud Always Free ARM VM, PostGIS 16, pgRouting
Site: Cloudflare Pages, global CDN
Tiles: GitHub Pages, PMTiles
Builds: GitHub Codespaces
Email: Resend SMTP, daily VM health reports at 08:00 EEST
The backup script: Written, tested, failing. Waiting for a cable.
There is no procurement department. There is no EU grant. There is one person, a drawer of old hardware, and a shopping list with one item on it.
Frankie is alive. But Frankie is not yet a server.
Top comments (0)