Teensy 4.1 - W5500 using SPI DMA

Interesting. Thanks for having a go at that. I think I was seeing upwards of ~11-14.7Mbps with the Teensy->Wiznet->eero->wifi setup, and about the same speeds as you’re seeing when using the wired adapter. Both tests with 30MHz SPI. Something’s up with the Wiznet module and wired Ethernet adapters.

I’m perplexed. Also befuddled.
 
Last edited:
For posterity, here were my results from yesterday with the Teensy->W5500 (WIZ850io)->eero node->wireless->Mac laptop:
Code:
------------------------------------------------------------
Client connecting to 10.0.0.21, TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------
[  1] local 10.0.0.71 port 53899 connected with 10.0.0.21 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-1.00 sec  1.75 MBytes  14.7 Mbits/sec
[  1] 1.00-2.00 sec  1.75 MBytes  14.7 Mbits/sec
[  1] 2.00-3.00 sec  1.50 MBytes  12.6 Mbits/sec
[  1] 3.00-4.00 sec  1.50 MBytes  12.6 Mbits/sec
[  1] 4.00-5.00 sec  1.38 MBytes  11.5 Mbits/sec
[  1] 5.00-6.00 sec  1.50 MBytes  12.6 Mbits/sec
[  1] 6.00-7.00 sec  1.62 MBytes  13.6 Mbits/sec
[  1] 7.00-8.00 sec  1.25 MBytes  10.5 Mbits/sec
[  1] 8.00-9.00 sec  1.38 MBytes  11.5 Mbits/sec
[  1] 9.00-10.00 sec  1.50 MBytes  12.6 Mbits/sec
[  1] 10.00-10.27 sec   128 KBytes  3.95 Mbits/sec
[  1] 0.00-10.27 sec  15.3 MBytes  12.5 Mbits/sec

Maybe the moon is in a slightly different orbital plane or my network topology changed, or maybe there's just more wireless noise (yesterday's test was done at night), but here's some results from just now:
Code:
------------------------------------------------------------
Client connecting to 10.0.0.21, TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------
[  1] local 10.0.0.71 port 54901 connected with 10.0.0.21 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-1.00 sec  1.00 MBytes  8.39 Mbits/sec
[  1] 1.00-2.00 sec   896 KBytes  7.34 Mbits/sec
[  1] 2.00-3.00 sec   896 KBytes  7.34 Mbits/sec
[  1] 3.00-4.00 sec   896 KBytes  7.34 Mbits/sec
[  1] 4.00-5.00 sec   768 KBytes  6.29 Mbits/sec
[  1] 5.00-6.00 sec   896 KBytes  7.34 Mbits/sec
[  1] 6.00-7.00 sec   896 KBytes  7.34 Mbits/sec
[  1] 7.00-8.00 sec   768 KBytes  6.29 Mbits/sec
[  1] 8.00-9.00 sec   896 KBytes  7.34 Mbits/sec
[  1] 9.00-10.00 sec   768 KBytes  6.29 Mbits/sec
[  1] 10.00-10.33 sec   128 KBytes  3.20 Mbits/sec
[  1] 0.00-10.33 sec  8.63 MBytes  7.01 Mbits/sec

Exact same code, except a different IP address and this topology: Teensy->WIZ850io->Belkin Ethernet USB-C adapter->Mac laptop (verified 100Mbps and full duplex):
Code:
------------------------------------------------------------
Client connecting to 192.168.1.3, TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------
[  1] local 192.168.1.2 port 55308 connected with 192.168.1.3 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-1.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 1.00-2.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 2.00-3.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 3.00-4.00 sec  0.000 Bytes  0.000 bits/sec
[  1] 4.00-5.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 5.00-6.00 sec  0.000 Bytes  0.000 bits/sec
[  1] 6.00-7.00 sec  0.000 Bytes  0.000 bits/sec
[  1] 7.00-8.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 8.00-9.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 9.00-10.00 sec  0.000 Bytes  0.000 bits/sec
[  1] 10.00-11.00 sec   128 KBytes  1.05 Mbits/sec
[  1] 0.00-12.31 sec   896 KBytes   596 Kbits/sec

Weird. Well, at least I know that my driver is written reasonably well. I'm baffled as to why the "hard link" is so much slower.
 
Another issue I'm experiencing is that ping doesn't work. I haven't dived too deeply using Wireshark or anything, but I'm just not seeing ICMP Echo Reply packets after sending multiple pings out the Teensy/W5500.
 
Was this W5500 measurement with the latest on github?

If I run "git log", the latest commit it prints is:

Code:
commit c11e8bb2c6819f40d9739c833baf24f3bf646387 (HEAD -> master, origin/master, origin/HEAD)
Author: Shawn Silverman <email redacted>
Date:   Thu Feb 12 20:56:14 2026 -0800

    w5500: Remove some socket-state-checking commented-out code
 
@PaulStoffregen I changed the MTU for the network the Teensy is attached to (Belkin adapter) to 1280 and then to 1400, down from 1500. The speeds are dramatically improved, like by a factor of 10. Would you be willing to try that?

I also tried some other experiments where I lowered the MTU on the Teensy side to 1400, keeping the max-frame-length the same, etc. And a few combinations. It turns out the MTU on the laptop side definitely needs to be less than the MTU on the Teensy side. I haven't played with too many combinations of max-frame-length, etc. But I do know that an MTU of 1280 or 1400 on the laptop side, with the 1500 MTU on the Teensy side, drastically increased throughput.

I might need to do more clever buffering. Currently, I drain as much data as possible from the W5500, then process everything in that buffer, then, when that buffer's empty, I get more data from the W5500. Maybe I need to check the W5500 again after each packet I process. I'll experiment with a circular buffer...
 
With a Wiznet W5500 and src/qnethernet_opts.h edited to uncomment #define QNETHERNET_DRIVER_W5500

Code:
iperf -c 192.168.195.236 -i 1
------------------------------------------------------------
Client connecting to 192.168.195.236, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  1] local 192.168.194.2 port 55168 connected with 192.168.195.236 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-1.00 sec  91.2 KBytes   748 Kbits/sec
[  1] 1.00-2.00 sec  48.5 KBytes   397 Kbits/sec
[  1] 2.00-3.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 3.00-4.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 4.00-5.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 5.00-6.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 6.00-7.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 7.00-8.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 8.00-9.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 9.00-10.00 sec  51.3 KBytes   420 Kbits/sec
[  1] 10.00-11.08 sec  25.7 KBytes   194 Kbits/sec
[  1] 0.00-11.08 sec   576 KBytes   426 Kbits/sec

Code:
Starting program...
MAC = 04:e9:e5:1a:34:11
Starting Ethernet with DHCP...
[Ethernet] Link ON, 100 Mbps, Full duplex
[Ethernet] Address changed:
    Local IP = 192.168.195.236
    Subnet   = 255.255.254.0
    Gateway  = 192.168.194.1
    DNS      = 192.168.194.1
Accepted connection: 192.168.194.2:55168
Processing input...
Rate = 425.839 kbps
I confirm these outputs also :)
I used a SFP based ethernet media converter (this is my "direct ethernet access" to the PC) and Wiznet still struggles as far as this scenario is concerned.
 
I confirm these outputs also :)
I used a SFP based ethernet media converter (this is my "direct ethernet access" to the PC) and Wiznet still struggles as far as this scenario is concerned.
Could you try setting your Ethernet port’s MTU to 1400 and see what happens? And then 1280.
 
[...two days later...] [again, in a French accent]

I believe I've solved it this time. I'm now seeing speeds greater than 19Mbps over the "direct" link (Belkin Ethernet USB-C adapter). I'm using much more aggressive buffering. Also, I'm leaving the interface's MTU at 1500. The text below is with this command: iperf -c 192.168.1.3 (no -i 1 option means it just uses the whole 10 seconds)

Code:
------------------------------------------------------------
Client connecting to 192.168.1.3, TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------
[  1] local 192.168.1.2 port 59733 connected with 192.168.1.3 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-10.08 sec  23.3 MBytes  19.4 Mbits/sec

@PaulStoffregen @istrateandrei26 would you mind testing one more time with the latest code on GitHub? (https://github.com/ssilverman/QNEthernet)

1. Don't forget to uncomment "#define QNETHERNET_DRIVER_W5500" in src/qnethernet_opts.h
2. Please run the SimpleIPerfServer example and optionally set the static IP (if you need to, and whatever addresses you need) like so:
C++:
const IPAddress kStaticIP{192, 168, 1, 3};
const IPAddress kSubnet{255, 255, 255, 0};
const IPAddress kGateway{192, 168, 1, 1};
Leave kStaticIP as-is (i.e. nothing) if you want to use DHCP.

One more note: I'm still trying to figure out why I can't receive Echo Reply ICMP packets, needed for sending pings.
 
Last edited:
Sorry for this late response...I am really busy these days but I promise I will return with results as far as the latest commit on GitHub repo is concerned :)
 
Back
Top