diary at Telent Netowrks

NixWRT next words#

Mon, 06 May 2019 10:02:50 +0000

Happy New Year!

Uh, yeah. I moved house quite recently and am only just starting to get back on top of stuff. Without further ado:

Things I have done

Some forward progress and some sideways movement. The forward progress is that I have been able to bring up WiFi on the GL-MT300A which was until recently my primary domestic router. I don't know how fast, reliable or stable it is, but judging by the number of OpenWRT patches I haven't applied, I suspect the answer is "not very, yet".

The sideways movement is that the top-level configs (backuphost.nix, wap.nix etc) are moved into the examples/ subdirectory and I have ceased pretending they're device-independent, because in practice they turn out not to be. Building abstraction layers over things like switch vlan settings is a distraction from building the things themselves - which is not to deny its importance, just to say that i don't want always to be having to do both at once.

Note that as of the time I write this, the repo is still in a state of some flux: the only thing that has a hope of building/booting is `defaultroute.nix` and that doesn't even work for use as a router as I haven't even tried to configure pppoe yet.

Things I have learned

The GL-MT300A is based on the Mediatek MTK7620A SoC (hopefully this means the hard parts are also done for the MT300Nv2, based on the very similar MTK7628NN - when I eventually find it again after moving house, I will try it). The Linux driver for this is rt2x00 but verifying this is correct/current/best was a long process because when I first compiled it into my kernel it utterly failed to find any hardware.

This took a certain amount of digging[1] to find out what the problem was. It turns out that although there's a config option for RT2800SOC which is enabled by SOC_MT7620 (which might make you think it's supposed to work) there is no description of this hardware in the upstream mt7620a device tree, so the kernel (reasonably) has no idea that it should be using this code for anything. The fix is two-fold: first, use the much more fully-featured device trees files from OpenWRT instead of upstream, and second, patch the driver so that it advertises a compatible attribute which matches the compatible attribute in the device tree node. It turns out that OpenWRT has done this already as well and now my kernel knows it has wlan hardware and a driver which are compatible with each other.

Well, allegedly compatible.

<6>[    1.310547] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 6352, rev 0500 detected                
<3>[    1.318533] ieee80211 phy0: rt2800_init_eeprom: Error - Invalid RF chipset 0xbadd detected          
<3>[    1.326981] ieee80211 phy0: rt2x00lib_probe_dev: Error - Failed to allocate device

The fix for this is also in OpenWRT patches: it needs to be told to get the eeprom whereabouts from the device tree, and then it can read the actual eeprom instead of I-have-no-idea-where-it's-getting-that-from and it gets the right RF chipset ID.

One other thing I noticed while doing this is that the OpenWRT patch set here didn't apply cleanly to any kernel version I had previously associated with OpenWRT, so I went looking a bit deeper to find out what they did.

What they did will surprise you! At least, I need to dig further to confirm this absolutely, but on the evidence so far, it's surprising me. Here's how it looks: Not only do they have different kernel minor versions for different target devices (currently 4.9 for atheros devices and 4.14 for everything else ) but they build these kernels to exclude all wireless support, and then build a completely separate out-of-tree module based on a completely different tree to provide the appropriate wifi support modules. See the mac80211 Makefile

I have not replicated this pattern for NixWRT, mostly because I want to see if I can get away without having to. Right now I'm picking patches from that set and applying them selectively to my basic monolithic kernel, and it seems to be working. In this regard, let me briefly tout the last item on my "things I learned" list: filterdiff , a command line tool which manipulates diff files so that you can drop patches applying to files you don't have, rewrite file names, skip hunks and so on, which means I can apply patches cleanly direct from OpenWRT and don't have to maintain patches-on-patches.

Next step: I will probably turn this into a wireless range extender on a separate ssid than my usual, just because everything I read about the reliability of rx200 driver suggests that if I want something stable and performant I should also apply the rest of those (currently inapplicable) patches to fix txpower and other random stuff which I have no idea what it is, and my userbase - the family - won't like dogfooding on my behalf. One of the (many, most irrelevant) changes in the new place is the internet connection: my new ISP sent me a free router with a dual band radio, which is in some ways much nicer than the ones I'm building NixWRT on (came pre-configured with all the IPv6 setup, plus 5GHz band is practically unused around here whereas 2.4G is more congested than the A406 on a Saturday afternoon) and in other ways is doing my head in (weird slow GUI, no real shell, no way to tell which of the 14 devices in the house is saturating the line) but it'll do for the moment. Apparently it's a broadcom chipset so porting NixWRT to it might not be the best possible use of time.

Next next steps, therefore: research dualband router SoCs I would like to port NixWRT to, and also find out how to set up all the IPV6, because native IPv6 is kinda new and kinda fun.

[1] Which is to say, alternately staring at it and googling randomly