Resetting USB / Ethernet Adapters from Linux

I bought a cheap UGREEN USB 3.0 Gigabit Ethernet Adapter, which is based on the ASIX AX88179 chipset. I found that it would periodically (usually while under load) stop transmitting/receiving packets, and shortly after that, its LEDs would turn off. Apparently AX88179 adapters are often flakey like this.

Cycling the Linux network interface running on top of the adapter using ip link set dev eth0 down and ip link set dev eth0 up didn’t get it working again. This is unfortunate since I run PPP over this ethernet link to connect to the internet. It seemed like the only fix was to reboot the machine.

However, I did find a solution to soft-reset the adapter by using the USBDEVFS_RESET ioctl system call.

Continue reading “Resetting USB / Ethernet Adapters from Linux”

Circuit for temperature-controlled dual-fan Raspberry Pi case

Several Raspberry Pi retailers are selling a CNC’d aluminium heatsink case for the Raspberry Pi, also known as the “Armour” case. While I actually wanted the passively cooled case (i.e. just a big heatsink), somehow I wound up with the dual-fan case instead.

The fans terminate in a combined dual-0.1″ plug, which they recommend connecting across the 5V and ground pins at positions 4 and 6 on the Pi’s GPIO header. This works fine, but the fans are on all the time, which I didn’t want (they’re not perfectly silent, and they’re also drawing power despite the Pi being relatively cool).

circuit with flyback diode added
Aluminium dual-fan case with the fans in the manufacturer’s recommended “always-on” configuration

It would be better to switch the fans on when the Pi gets above a particular temperature – and this post explains how. Thanks to Jim for supplying hardware, knowledge and soldering skills to make a solution possible.

Software

From the software side, this is easily achieved. Some other sites recommend writing a userspace daemon in Python, but we can simply add a device-tree overlay to have the kernel do the monitoring and switching:

# in /boot/config.txt
dtoverlay=gpio-fan

By default, this sets GPIO12 high when the Pi hits 55C, and turns it off once the Pi gets below 45C. Theoretically, this also supports hardware PWM to control the fan speed, although the speed isn’t configurable through the overlay.

Hardware

So, how do we wire things up so that when GPIO12 goes high, we can supply the fans with the power they need? GPIO12 only supplies 3.3V and at most 16mA, so connecting the fans directly will damage the Pi. The hard-to-find gpio-fan overlay source code suggests using a 2N7002 N-MOSFET like so:

circuit with 2n7002 transistor's Gate connected to GPIO12, and fan between 5V and the 2n7002's Drain; the transistor's Source is connected to ground

However, this doesn’t work for the dual-fans. And while it might work for single fans, there are still some additional improvements that can help protect the Pi.

Continue reading “Circuit for temperature-controlled dual-fan Raspberry Pi case”

Internode IPv6 on Linux with systemd-networkd

Internode’s instructions for configuring IPv6 routing on linux are pretty terse, merely giving some suggestions for using WIDE DHCPv6 and radvd. On modern Linux with systemd, these extra daemons are unnecessary; all that’s required is systemd-networkd. This post describes the problems and how I got dual-stack IPv4/IPv6 routing over Internode’s NBN service, using a Raspberry Pi running Debian Buster.

Firstly, here’s all the things we want the router to do:

  • Create a PPPoE connection to Internode via the NBN (HFC).
  • Establish the IPv6 address of the upstream router and create a default route there.
  • Issue Router Advertisements (RA) to other hosts on the LAN so that they can configure their global IPv6 address and default route using SLAAC.
  • Act as a DHCPv6 client for Prefix Delegation. It’s not obvious why this is required: Internode allocates a static /56 prefix, and I can statically configure my router to advertise that in its RA. However, it turns out that without the DHCP lease, upstream routes aren’t created for hosts in the /56 prefix!

Glen Turner has an excellent guide for a setup on Debian Wheezy consistent with Internode’s recommendation, using the radvd and wide-dhcpv6-client packages. But on Debian Buster, this feels quite outdated: wide-dhcp6cd will exit immediately (rather than wait) if its config mentions an interface that doesn’t exist. Hence systemd disables it because of the fail-loop it enters on system boot when ppp0 doesn’t exist. On top of this, there’s no good logging level for wide-dhcp6cd; the “debug” level pours out minutiae of config-file parsing, while the merely “verbose” level gives no indication about what the DHCP replies contain. It’s also using a SysV-style init script rather than a modern systemd service.

I’ve also avoided using GNOME’s NetworkManager, which I feel is too bloated for a headless router in a stable network topology.

My configs follow.

Continue reading “Internode IPv6 on Linux with systemd-networkd”