Patching OpenWrt with a new driver

Jun 23, 2023

I wrote a post on compiling OpenWrt from source a few months ago. Since then, I've been playing around with its source, building new images with it to test on virtual machines. OpenWrt finally added support for Orange Pi R1 Plus (LTS) for their next release, 23.05. And with a new driver for RTL8153, a chipset used in the board, I decided to go back to patching OpenWrt one more time.

Kernel patch

As shown from my previous post on OpenWrt for Orange Pi R1 Plus, kernel patches are how they affect the kernel to their preferences for running OpenWrt, like allowing unsupported devices to run the OS. The Linux kernel source has upstreamed dts for R1 Plus on v6.3 and LTS on v6.4, and now is backported to kernel 5.15 for OpenWrt 23.05 using kernel patches. Patches are created using either diff or git diff.

How to create diff

It's actually quite easy. Just follow this command:

diff -rupN <source> <target> > <output>

With:

- r to compare with subdirectories, subfolders

- u outputs NUM (default 3) lines of unified context (yeah I don't get it)

- p shows which C function each change is in

- N treats absent files as empty

Or:

git diff <source> <target> > <output>

Patch new driver into the kernel

I first tried using /dev/null as source to diff against r8152.c file from Realtek, and then put it in as patch. I deleted a patch related to r8152.c so it remained original to kernel source. I put the patch in target/linux/generic/hack-5.15, same as where I deleted the previous patch. But replacing the kernel driver wasn't easy, I tried

--- a/drivers/net/usb/r8152.c

+++ /dev/null

--- /dev/null

+++ b/drivers/net/usb/r8152.c

or

--- /dev/null

+++ b/drivers/net/usb/r8152.c

The source didn't compile due to the file already existing in the kernel.

So I did the hard way. I went into dl folder, extract r8152.c from linux-5.15.117.tar.xz (at the time OpenWrt was built on kernel 5.15.117) then diff against the same file from Realtek. It compiled successfully. I could run it well on a virtual machine.

Apparently, the compiler doesn't read anything above the first change in the patch. So the lines before that is considered comments to the compiler. I added a note to say that this driver is not from the kernel source.

Patch new driver into ImmortalWrt

I also used ImmortalWrt 21.02 for testing their software offloading TurboACC. Originally, ImmortalWrt wouldn't compile with the original source because of lack of 'libcap'. I found out that the library existed in 22.03 of OpenWrt, not in 21.02 which was the base for ImmortalWrt. So I copied it from OpenWrt at package/libs/libcap and took it to ImmortalWrt. It compiled.

Test RTL8153 using OpenWrt

I tested it using my device and iperf3. The LAN port contains RTL8153 chipset and I tested it half-duplex, 1 download 1 upload separately. Download from my laptop to the LAN port got me 940 Mbps, which was max bandwidth for 1 Gbps Ethernet:

[ ID] Interval Transfer Bitrate Retr Cwnd

[ 5] 0.00-1.00 sec 113 MBytes 950 Mbits/sec 0 708 KBytes

[ 5] 1.00-2.00 sec 111 MBytes 933 Mbits/sec 0 758 KBytes

[ 5] 2.00-3.00 sec 112 MBytes 944 Mbits/sec 0 799 KBytes

[ 5] 3.00-4.00 sec 111 MBytes 933 Mbits/sec 0 841 KBytes

[ 5] 4.00-5.00 sec 111 MBytes 933 Mbits/sec 0 901 KBytes

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 559 MBytes 939 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 557 MBytes 934 Mbits/sec receiver

Upload on original driver reached only 630 Mbps:

[ ID] Interval Transfer Bitrate

[ 5] 0.00-1.00 sec 70.1 MBytes 588 Mbits/sec

[ 5] 1.00-2.00 sec 74.6 MBytes 626 Mbits/sec

[ 5] 2.00-3.00 sec 75.2 MBytes 631 Mbits/sec

[ 5] 3.00-4.00 sec 75.4 MBytes 632 Mbits/sec

[ 5] 4.00-5.00 sec 74.7 MBytes 627 Mbits/sec

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 371 MBytes 622 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 370 MBytes 621 Mbits/sec receiver

Upload after patch reached 880 Mbps:

[ ID] Interval Transfer Bitrate

[ 5] 0.00-1.00 sec 97.8 MBytes 821 Mbits/sec

[ 5] 1.00-2.00 sec 107 MBytes 894 Mbits/sec

[ 5] 2.00-3.00 sec 107 MBytes 896 Mbits/sec

[ 5] 3.00-4.00 sec 103 MBytes 861 Mbits/sec

[ 5] 4.00-5.00 sec 106 MBytes 885 Mbits/sec

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 522 MBytes 876 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 519 MBytes 871 Mbits/sec receiver

Test RTL8153 using ImmortalWrt

I also tested the RTL8153 chipset with ImmortalWrt 21.02 original driver. It got me 940 Mbps download:

[ ID] Interval Transfer Bitrate Retr Cwnd

[ 5] 0.00-1.00 sec 113 MBytes 948 Mbits/sec 0 396 KBytes

[ 5] 1.00-2.00 sec 112 MBytes 941 Mbits/sec 0 396 KBytes

[ 5] 2.00-3.00 sec 111 MBytes 932 Mbits/sec 0 563 KBytes

[ 5] 3.00-4.00 sec 112 MBytes 940 Mbits/sec 0 563 KBytes

[ 5] 4.00-5.00 sec 112 MBytes 938 Mbits/sec 0 563 KBytes

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 560 MBytes 940 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 558 MBytes 935 Mbits/sec receiver

and 720 Mbps upload:

[ ID] Interval Transfer Bitrate

[ 5] 0.00-1.00 sec 84.5 MBytes 709 Mbits/sec

[ 5] 1.00-2.00 sec 87.5 MBytes 734 Mbits/sec

[ 5] 2.00-3.00 sec 86.5 MBytes 726 Mbits/sec

[ 5] 3.00-4.00 sec 85.5 MBytes 717 Mbits/sec

[ 5] 4.00-5.00 sec 86.9 MBytes 729 Mbits/sec

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 433 MBytes 726 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 431 MBytes 723 Mbits/sec receiver

I tested RTL8153 again after patch with iperf3 upload. It got 870 Mbps:

[ ID] Interval Transfer Bitrate

[ 5] 0.00-1.00 sec 103 MBytes 862 Mbits/sec

[ 5] 1.00-2.00 sec 103 MBytes 867 Mbits/sec

[ 5] 2.00-3.00 sec 103 MBytes 862 Mbits/sec

[ 5] 3.00-4.00 sec 104 MBytes 870 Mbits/sec

[ 5] 4.00-5.00 sec 105 MBytes 879 Mbits/sec

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 521 MBytes 874 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 517 MBytes 868 Mbits/sec receiver

Test YT8531c using OpenWrt and ImmortalWrt

I couldn't test the WAN port with YT8531c chipset. I couldn't get IP address on my laptop, despite setting the WAN port to have the same settings as the LAN port for DHCP. I did try in vain to patch it using dts patch of the R1 Plus LTS board. As you can see, they had updated Mootorcomm driver and the device tree source with new values like clk-out-frequency-hz, keep-pll-enabled, auto-sleep-disabled. Maybe there is something wrong with the driver, because this also happened on ImmortalWrt 23.05. Using Armbian, however, I could use the WAN port normally.

So in the end, OpenWrt 23.05 shouldn't be used just yet.

I rolled back to OpenWrt 22.03. I tested the WAN port with iperf3 again.

Download 940 Mbps:

[ ID] Interval Transfer Bitrate Retr Cwnd

[ 5] 0.00-1.00 sec 113 MBytes 948 Mbits/sec 0 551 KBytes

[ 5] 1.00-2.00 sec 113 MBytes 945 Mbits/sec 0 551 KBytes

[ 5] 2.00-3.00 sec 111 MBytes 932 Mbits/sec 0 551 KBytes

[ 5] 3.00-4.00 sec 112 MBytes 943 Mbits/sec 0 551 KBytes

[ 5] 4.00-5.00 sec 112 MBytes 937 Mbits/sec 0 551 KBytes

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 561 MBytes 941 Mbits/sec 0 sender

[ 5] 0.00-5.01 sec 559 MBytes 935 Mbits/sec receiver

Upload 930 Mbps:

[ ID] Interval Transfer Bitrate

[ 5] 0.00-1.00 sec 105 MBytes 881 Mbits/sec

[ 5] 1.00-2.00 sec 111 MBytes 931 Mbits/sec

[ 5] 2.00-3.00 sec 111 MBytes 931 Mbits/sec

[ 5] 3.00-4.00 sec 111 MBytes 934 Mbits/sec

[ 5] 4.00-5.00 sec 112 MBytes 937 Mbits/sec

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval Transfer Bitrate Retr

[ 5] 0.00-5.00 sec 552 MBytes 925 Mbits/sec 0 sender

[ 5] 0.00-5.00 sec 550 MBytes 923 Mbits/sec receiver

ImmortalWrt 21.02 gave out similar results.

Note about offloading

These tests have been performed with and without [software offloading]. Doesn't seem like it does anything. Whether OpenWrt or TurboACC from ImmortalWrt. Packet steering also doesn't work, either.

Reason for better performance on ImmortalWrt compared to OpenWrt

As you can see when using RTL8153 original driver, OpenWrt only reached 630 Mbps while ImmortalWrt got 720 Mbps in iperf3 upload is because, ImmortalWrt overclocked the processor, Rockchip RK3328, from stock 1.3 Ghz to 1.6 Ghz. ImmortalWrt has a patch where they add clock frequencies to the operating performance point (OPP) table. ImmortalWrt was running RK3328 at 1.6 Ghz max.

--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi

+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi

@@ -140,6 +140,21 @@

opp-microvolt = <1300000>;

clock-latency-ns = <40000>;

};

+ opp-1392000000 {

+ opp-hz = /bits/ 64 <1392000000>;

+ opp-microvolt = <1350000>;

+ clock-latency-ns = <40000>;

+ };

+ opp-1512000000 {

+ opp-hz = /bits/ 64 <1512000000>;

+ opp-microvolt = <1450000>;

+ clock-latency-ns = <40000>;

+ };

+ opp-1608000000 {

+ opp-hz = /bits/ 64 <1608000000>;

+ opp-microvolt = <1450000>;

+ clock-latency-ns = <40000>;

+ };

};

amba {

References:

- Kernel Patch

- RTL8153 linux driver

- OpenWrt 23.05 RTL8153 patch