Skip to content

Instantly share code, notes, and snippets.

@MadLittleMods
Last active October 21, 2024 23:46
Show Gist options
  • Save MadLittleMods/3005bb13f7e7178e1eaa9f054cc547b0 to your computer and use it in GitHub Desktop.
Save MadLittleMods/3005bb13f7e7178e1eaa9f054cc547b0 to your computer and use it in GitHub Desktop.

Realtek 8153

Download

Current version: 1.0.19 1.0.15 (as of 2018-12-10)

https://www.realtek.com/en/component/zoo/category/network-interface-controllers-10-100-1000m-gigabit-ethernet-usb-3-0-software

http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=1&PNid=13&PFid=56&Level=5&Conn=4&DownTypeID=3&GetDown=false

Realtek GBE USB

  • Gigabit ethernet
  • USB hub

Gather Info




  • Launch a terminal/shell
  • ioreg -p IOUSB -w0
  • ioreg -p IOUSB -w0 -l: For more info
+-o Root  <class IORegistryEntry, id 0x100000100, retain 14>
  +-o Root Hub Simulation Simulation@14000000  <class AppleUSBRootHubDevice, id 0x1000002fa, registered, matched, active, busy 0 (6 ms), retain 13>
    +-o USB2.0 Hub             @14100000  <class AppleUSBDevice, id 0x1000002fb, registered, matched, active, busy 0 (43 ms), retain 14>
    +-o Apple Internal Keyboard / Trackpad@14400000  <class AppleUSBDevice, id 0x1000002ff, registered, matched, active, busy 0 (96 ms), retain 22>
    +-o USB3.0 Hub             @14500000  <class AppleUSBDevice, id 0x100000363, registered, matched, active, busy 0 (54 ms), retain 15>
    | +-o USB 10/100/1000 LAN@14540000  <class AppleUSBDevice, id 0x100000418, registered, matched, active, busy 0 (73 ms), retain 18>
    +-o Bluetooth USB Host Controller@14300000  <class AppleUSBDevice, id 0x1000003d8, registered, matched, active, busy 0 (58 ms), retain 24>
Terminal output snippet from `ioreg -p IOUSB -w0 -l`
+-o USB3.0 Hub             @14500000  <class AppleUSBDevice, id 0x100000363, registered, matched, active, busy 0 (54 ms), retain 15>
    | | {
    | |   "sessionID" = 2480892594
    | |   "iManufacturer" = 1
    | |   "bNumConfigurations" = 1
    | |   "idProduct" = 2066
    | |   "bcdDevice" = 37009
    | |   "Bus Power Available" = 900
    | |   "USB Address" = 5
    | |   "bMaxPacketSize0" = 9
    | |   "iProduct" = 2
    | |   "iSerialNumber" = 0
    | |   "bDeviceClass" = 9
    | |   "Built-In" = No
    | |   "locationID" = 340787200
    | |   "bDeviceSubClass" = 0
    | |   "bcdUSB" = 768
    | |   "USB Product Name" = "USB3.0 Hub             "
    | |   "PortNum" = 5
    | |   "non-removable" = "no"
    | |   "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | |   "bDeviceProtocol" = 3
    | |   "IOUserClientClass" = "IOUSBDeviceUserClientV2"
    | |   "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=3,"CapabilityFlags"=65536,"MaxPowerState"=4,"DriverPowerState"=3}
    | |   "Device Speed" = 3
    | |   "USB Vendor Name" = "VIA Labs, Inc.         "
    | |   "idVendor" = 8457
    | |   "IOGeneralInterest" = "IOCommand is not serializable"
    | |   "IOClassNameOverride" = "IOUSBDevice"
    | | }
    | |
    | +-o USB 10/100/1000 LAN@14540000  <class AppleUSBDevice, id 0x100000418, registered, matched, active, busy 0 (73 ms), retain 18>
    |     {
    |       "sessionID" = 3379212797
    |       "iManufacturer" = 1
    |       "bNumConfigurations" = 2
    |       "idProduct" = 33107
    |       "bcdDevice" = 12288
    |       "Bus Power Available" = 900
    |       "USB Address" = 8
    |       "bMaxPacketSize0" = 9
    |       "iProduct" = 2
    |       "iSerialNumber" = 3
    |       "bDeviceClass" = 0
    |       "Built-In" = No
    |       "locationID" = 341049344
    |       "bDeviceSubClass" = 0
    |       "bcdUSB" = 768
    |       "USB Product Name" = "USB 10/100/1000 LAN"
    |       "PortNum" = 4
    |       "non-removable" = "no"
    |       "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    |       "bDeviceProtocol" = 0
    |       "IOUserClientClass" = "IOUSBDeviceUserClientV2"
    |       "IOPowerManagement" = {"ChildrenPowerState"=4,"DevicePowerState"=0,"CurrentPowerState"=4,"CapabilityFlags"=32768,"MaxPowerState"=4,"DriverPowerState"=4}
    |       "Device Speed" = 3
    |       "USB Vendor Name" = "Realtek"
    |       "idVendor" = 3034
    |       "IOGeneralInterest" = "IOCommand is not serializable"
    |       "USB Serial Number" = "002427FE48F6"
    |       "IOClassNameOverride" = "IOUSBDevice"
    |     }
    |

  • Launch a terminal/shell
  • ifconfig
en4: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=2b<RXCSUM,TXCSUM,VLAN_HWTAGGING,TSO4>
	ether 00:24:27:fe:48:f6
	inet 192.168.1.135 netmask 0xffffff00 broadcast 192.168.1.255
	media: autoselect (1000baseT <full-duplex,flow-control>)
	status: active

Reload OSX driver (kext)

The driver is located at

  • /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleRTL815X*.kext
  • /Library/Extensions/AppleRTL815X*.kext

Here are the namespaces:

  • com.realtek.driver.AppleRTL815XEthernet
  • com.realtek.driver.AppleRTL815XComposite

See http://osxdaily.com/2015/06/24/load-unload-kernel-extensions-mac-os-x/

With normal operation with only the network cable plugged in, I only see com.realtek.driver.AppleRTL815XEthernet loaded.

# Unload
sudo kextunload /Library/Extensions/AppleRTL815XEthernet109.kext
sudo kextunload /Library/Extensions/AppleRTL815XComposite109.kext

# Load
sudo kextload /Library/Extensions/AppleRTL815XEthernet109.kext
sudo kextload /Library/Extensions/AppleRTL815XComposite109.kext

# Find if loaded
kextstat | grep com.realtek.driver.AppleRTL815XEthernet
kextstat | grep com.realtek.driver.AppleRTL815XComposite

Perhaps clear the Kernel cache

sudo rm -rf /System/Library/Caches/com.apple.kext.caches

I got a new USB ethernet adapter and use the native driver

I got a new USB ethernet adapter because the old one had lots of issues (hence the gist in the first place). But it still uses the same Realtek 8153 chip although am using the native driver though now, AppleUSBECM.kext

In terms of my previous issues, I remember that when I clicked the little lock in the browser to view the cert, it would crash my computer. But the disconnects that required a restart were the bigger issue. (personal reference link)

I'm currently running macOS Mojave 10.14

@zenczykowski
Copy link

And I wrote all of the above to explain why 8153 NCM is unlikely to happen.
It's not a missing Apple 8153 NCM driver.
What's actually missing is NCM protocol support in the USB ethernet dongle itself.
Assuming the dongle's firmware is updateable (might not be... who knows), you'd need to load new firmware into it that supports NCM (probably doable at the factory, likely harder/more risky in a user's hands - sometimes firwmare is intentionally locked down [so you can't flash it over usb] and thus might require disassembling the dongle and/or soldering in [jtag or other] connectors).
Additionally someone (presumably at Realtek...) would need to write that firmware (there might not even be enough room for it...). etc.

That said... there is a rumour of there being an NCM capable 8153 chip... I'm not sure whether it should be believed, or if some manufacturer actually runs a more complex multi-chip setup, or if someone actually developed an NCM capable firmware for the chip, even though [at a cursory glance per the spec sheet] Realtek does not appear to provide one...

https://gist.github.com/MadLittleMods/3005bb13f7e7178e1eaa9f054cc547b0?permalink_comment_id=4273488#gistcomment-4273488

But do note that's a monitor not a dongle... maybe it's not actually a RTL8153???
or it's a newer version of the chip (8153 is old... there's lots of revs)? or a chip with a much newer firmware?
or maybe Dell put in more eeprom to support a large more full featured firmware with NCM support?

Who knows...

--

https://forums.macrumors.com/threads/usb-c-ethernet-unreliable.2287743/post-31376857 and previous/next pages claim that for RTL8156 the USB reported version depends on the chip subversion:
Version: 30.00 RTL8156
Version: 31.00 RTL8156B
Version: 31.04 RTL8156B(S)G (ie. both the RTL8156BG and the RTL8156BSG)
and that the later versions work much better with Mac.
I wonder why... perhaps subtle bugs in the NCM protocol implementation on the chip?

(also note that RTL8153 can also report Version: 30.00)

Maybe the chip version only affects the default firmware, and there's some way (for manufacturers) to load in newer fw?

https://www.realtek.com/en/products/connected-media-ics/item/rtl8156b-s-g-cg - ECM & NCM
https://www.realtek.com/en/products/connected-media-ics/item/rtl8153b-vb-cg - lists ECM, does not list NCM...

https://www.asix.com.tw/en/product/USBEthernet/Super-Speed_USB_Ethernet/AX88179A - NCM

Aquantia was bought by Marvell, and all signs of USB ethernet chips from them seem to have more or less vanished,
although I know they exist (I have some dongles), and from vague recollection they supported NCM too.

https://www.marvell.com/content/dam/marvell/en/psg/marvell_psg.pdf
lists USB AQC111U-B0-C and AQC112U-B0-C

@zenczykowski
Copy link

Final note: the r8153_ecm linux driver is really just a very minor extension to the standard generic linux cdc ecm driver.
That's why it's just 170 lines (and much of that is boilerplate).

If I'm reading it right, it uses the standard ECM driver for everything, except that it uses a vendor extension for MII - which IFIRC is a way to report (and or configure advertised) link speed/duplex (see https://linux.die.net/man/8/mii-tool ).

The normal Linux ECM driver is normally prevented from binding to an 8153 device, so that the more specific driver will be used instead.

https://github.com/torvalds/linux/blob/master/drivers/net/usb/Kconfig#L637 is pretty crazy.
The lack of a string doc on the tristate line means it is not actually user configurable (there is no build time option to choose whether the driver is enabled or not) - hence the kernel configuration file gets to automatically select whether it should be enabled during build time.

config USB_RTL8153_ECM
tristate
depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
default y

Roughly translates as:

  • define a tristate (No, Module, Yes=built-in) configuration option called USB_RTL8153_ECM, which is not user configurable (via .config).
  • it requires USB_NET_CDCETHER (becomes it's an extension of the CDCETHER, aka ECM driver)
  • it defaults to enabled (y)
    Here stuff gets really finicky.
  • because it depends on USB_NET_CDCETHER, it automatically demotes from 'y' to 'm' if CDCETHER (the ECM driver) is a module.
    (you can't have the driver extension be built into the kernel, if the driver it extends isn't built in itself)
    It gets worse:
  • it also depends on (USB_RTL8152 || USB_RTL8152=n) which actually always evaluates to true.
    This is because USB_RTL8152 is either Yes or Module or No.
    Yes and Module make the first half of the || true, while No makes the second half of the || true.
  • okay, so why do this? Because this is actually tristate logic, not normal boolean.
    USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
    has the curious property that USB_NET_CDCETHER=y + USB_RTL8152=m results in the 'default y' being demoted to 'm'.
    (because we're depending on a module)
    Why do this? Because if you build the ECM driver into the kernel, and build the 'better' native 8152 driver as a module, you want to be able to easily load the 8152 driver and have it bind to the device, instead of having the built in driver win. This requires the extension to be a module, even though the thing it extends is builtin.
    Basically if both USB_NET_CDCETHER (ie. ECM) and R8153_ECM were builtin, but USB_RTL8152 was a module, the module would never load, since the builtin driver would bind the device when you plug it in.
    Linux does provide a way to manually unbind the built-in driver, and manually bind in the other one, but it's a hassle, and better to just make the extension a module.

This probably still isn't ideal... since I'm not sure what determines which of the 2 drivers wins if both are modular... likely it's random (or alphabetical sort order or something)

@Monstergerm
Copy link

Has anybody noticed dropped outgoing packets as well as Oerrs with the NCM driver?
I have three adapters but only the one using the Realtek 8153 chip set and thus ECM driver does not show these errors. Both 8156 and AX88179A chips using NCM driver have huge percentage of Oerrs (Terminal netstat -di -I en4 command; if your interface is en4).

Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll Drop
en4 1500 <Link#26> 00:XX:XX:XX:XX:XX 828846 0 88393 40649 0 9940

@april
Copy link

april commented Oct 26, 2023

That said... there is a rumour of there being an NCM capable 8153 chip... I'm not sure whether it should be believed, or if some manufacturer actually runs a more complex multi-chip setup, or if someone actually developed an NCM capable firmware for the chip, even though [at a cursory glance per the spec sheet] Realtek does not appear to provide one...

The RTL8153D uses the FIRMWARE_8156B_2 firmware, same as the RTL8156B; the Linux driver shows the only difference is that 56B supports 2.5G, while the 53D only does 1G. Presumably the new RTL8153E is NCM as well.

I wrote that Macrumors post about the RTL8156B(S)G, and certainly noticed better performance than the previous chip revisions. This was observed on Linux as well.

@web-xyz
Copy link

web-xyz commented Nov 12, 2023

Has anybody noticed dropped outgoing packets as well as Oerrs with the NCM driver? I have three adapters but only the one using the Realtek 8153 chip set and thus ECM driver does not show these errors. Both 8156 and AX88179A chips using NCM driver have huge percentage of Oerrs (Terminal netstat -di -I en4 command; if your interface is en4).

Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll Drop en4 1500 <Link#26> 00:XX:XX:XX:XX:XX 828846 0 88393 40649 0 9940

I have a similar issue with the Belkin USB-C to 2.5 Gb Ethernet Adapter (SKU: INC012btBK) with firmware version 31.04 (so supposedly using RTL8156B(S)G) on a MacBook Pro 16-inch, 2019 with Sonoma 14.1.1: there are Oerrs in the netstat output!

There are no Oerrs with the Thunderbolt to Gigabit Ethernet Adapter (with the Thunderbolt 3 (USB-C) to Thunderbolt 2 Adapter) on the same laptop.

Does everybody with an adapter using RTL8156 / RTL8156B / RTL8156B(S)G have Oerrs?

What do exactly output errors mean and entail?

Any idea on how to fix the issue?

Thanks.

@lcharette
Copy link

lcharette commented Mar 3, 2024

Bit of update as of March 2024 and macOS Sonoma 14.3.1. Look like this is still an issue. Considering business like OWC still sell Thunderbolt dock with the 8156 chipset without any warning about limited capability of the Gigabit port for Mac users, it's a bit frustrating to say the least.

After a bit a of research and trial and error, I found it is possible to achieve gigabit speed on MacOS with the Realtek 8156 chipset, but with a huge caveat, as far as my finding shows : (tl;dr) You need to install the Realtek driver with SIP disabled and keep SIP disabled.

Since this most sources on the Internet point to this Gist, I share below is my process and findings, in case it can help anyone. For my part, I'll most likely be returning the OWC dock and look for a better alternative, as the lack of warning/information from OWC left a bitter taste in my mouth...


As many pointed out, by default, MacOS will use the com.apple.DriverKit.AppleUserECM driver for any Ethernet port passed through USB using the Realtek 8156 chipset. This Apple supplied driver limits the overall speed of Ethernet connection through USB/Thundnerbolt to ~400 Mbps for some reason. The overall solution is to install the official driver from Realtek. However, it hasn't been updated since 2020 and does not appear to be compatible with Apple's new extension privacy feature introduced in Big Sur (11.0). This is why when googling this issue, you'll find a lot of people claiming installing the driver fix the issue, only to realized the comments are probably from 2021.

These are the steps I used on my Intel MacBook Air to get the driver to load, by disabling SIP :

  1. Reboot in Recovery mode : cmd+R
  2. Open Terminal
  3. Disable SIP : csrutil disable
  4. Close Terminal and reboot
  5. Install Realtek Drivers from their website, version 1.0.22 for "MAC OS 10.9 to 10.15". Accept any prompt in system preferences and REBOOT
  6. Plug-in Thunderbolt dock / adapter with 8153 chipset. This is important, as the next step will only be displayed when the adapter is connected. In other words, when you reboot, nothing is loaded. When you connect the adapter, all three extensions listed below will be loaded dynamically and stay loaded until next reboot.
  7. You can make sure com.realtek.driver.AppleRTL815XEthernet extension is loaded from terminal : sudo kmutil showloaded | grep -i realtek. You should see something similar:
$ kmutil showloaded | grep -i realtek
No variant specified, falling back to release
  203    0 0xffffff7f96289000 0xffc      0xffc      com.realtek.driver.AppleRTL815XComposite (1.0.22) BA984F53-C67B-31DB-82FA-9146A9680FCA <74 7 6 3 1>
  204    0 0xffffff8001dbc000 0x7ff4     0x7ff4     com.apple.driver.usb.realtek8153patcher (5.0.0) 1C97FD90-1304-3956-B4D6-272E31074AF6 <30 7 6 3 1>
  205    0 0xffffff7f96235000 0x51ff8    0x51ff8    com.realtek.driver.AppleRTL815XEthernet (1.0.22) E7B07C4A-4CF4-3B58-9027-B592E4A041F3 <119 54 30 7 6 3 1>
  1. System Information (Apple menu > System Settings, then click General in the sidebar. (You may need to scroll down.) Click About on the right, then click System Report) can also tell you which driver your Ethernet connection is currently using. Select "Ethernet" under "Hardware", and select "USB 10/100/1000 LAN". There you should see com.realtek.driver.AppleRTL815XEthernet under "Driver":
2024_03_03_SysInfo_Ethernet_RT110

At this point, everything should be good as you're actually using the Realtek driver and you should be able to run a speed test with ~Gigabit speed, even after a couple of reboots :
2024-03-03_Win

However, remember SIP is currently disabled on you Mac!. To re-enable it :

  1. Reboot in Recovery mode : cmd+R
  2. Open Terminal
  3. Disable SIP : csrutil disable
  4. Close Terminal and reboot

And now, you're back to square one. macOS will revert back to the com.apple.DriverKit.AppleUserECM driver.
2023_03_03_FAIL

SpepedTest_FAIL

$ sudo kmutil showloaded | grep -i realtek
No variant specified, falling back to release
  203    0 0xffffff7f9621d000 0xffc      0xffc      com.realtek.driver.AppleRTL815XComposite (1.0.22) BA984F53-C67B-31DB-82FA-9146A9680FCA <74 7 6 3 1>
  204    0 0xffffff8001dbc000 0x7ff4     0x7ff4     com.apple.driver.usb.realtek8153patcher (5.0.0) 1C97FD90-1304-3956-B4D6-272E31074AF6 <30 7 6 3 1>

I tried manually loading the kext located in /Library/Extensions/ using the Terminal (https://developer.apple.com/documentation/apple-silicon/installing-a-custom-kernel-extension), however the following error is displayed.

$ sudo kextload /Library/Extensions/AppleRTL815XEthernet*.kext

Executing: /usr/bin/kmutil load -p /Library/Extensions/AppleRTL815XEthernet110.kext
Error Domain=KMErrorDomain Code=71 "Unsupported Error: one or more extensions are unsupported to load: 	Kext com.realtek.driver.AppleRTL815XEthernet v1.0.22 in executable kext bundle com.realtek.driver.AppleRTL815XEthernet at /Library/StagedExtensions/Library/Extensions/AppleRTL815XEthernet110.kext" UserInfo={NSLocalizedDescription=Unsupported Error: one or more extensions are unsupported to load: 	Kext com.realtek.driver.AppleRTL815XEthernet v1.0.22 in executable kext bundle com.realtek.driver.AppleRTL815XEthernet at /Library/StagedExtensions/Library/Extensions/AppleRTL815XEthernet110.kext}

Same message with :

$ sudo kmutil clear-staging
$ sudo kmutil load -b com.realtek.driver.AppleRTL815XEthernet

You might even get a System Preference warning telling you the extension is out of date
WarningUpdate

Which is expected under SIP and macOS Sonoma. Disabling SIP and running the same command again does allow the kext to be loaded, and after a confirmation from System Preferences and a reboot, the driver is correctly loaded again. However, SIP is still disabled, so enabling it once again brings you back to square one.

Note that System Information does show the extensions as being present under Software -> Extensions -> AppleRTL815XEthernet110 when SIP is disabled, but still won't use it as a driver :
SysIno_NotLaoded

I believe at this point the driver *is* "installed", but somehow SIP prevent it from being used.

Side note, while @LeuschkeTressa comment was useful to understand the issue, it didn't solve the issue either (and appears to be for another issue altogether).


The most important piece of documentation from Apple can be found here: https://support.apple.com/en-ca/guide/deployment/depa5fb8376f/web

In macOS 11 or later, if third-party kernel extensions (kexts) are enabled, they can’t be loaded into the kernel on demand. They require the user’s approval and restarting of the macOS to load the changes into the kernel, and they also require that the secure boot be configured to Reduced Security on a Mac with Apple silicon.

When a new kext is installed and there’s an attempt to load it, a restart must be initiated by the user from the warning dialog in:

  • macOS 13 or later: Apple menu > System Settings > Privacy & Security.
  • macOS 12.0.1 or earlier: Apple menu > System Preferences, > Security & Privacy.
    This restart initiates the rebuild of the AuxKC before to the kernel booting.

If System Integrity Protection (SIP) is enabled, the signature of each kext is verified before being included in the AuxKC.
If SIP is disabled, the kext signature isn’t enforced.
This approach allows Permissive Security flows for developers or users who aren’t part of the Apple Developer Program to test kexts before they’re signed.

tl;dr Whatever you do, any extension must be approved from System Preference and won't ever be applied until reboot.

I didn't try to Change security settings on the startup disk, since I don't own an Apple Silicon Mac. However, this doesn't sound like a valid solution since you're lowering the security features of your Mac. As Apple mention themselves :

Important: Kexts are no longer recommended for macOS. Kexts risk the integrity and reliability of the operating system. Users should prefer solutions that don’t require extending the kernel and use system extensions instead.

So until Apple themselves fix this or Realtek release updated drivers, stay away from 8153 chipset.

References

@halfbrilliant
Copy link

Sorry, all that follows is technically OT and I will understand if it’s removed: All I want is an Ethernet port capable of Native (or at any rate, not making my CPU do the work, i.e. allowing it to offload it to the Ethernet hardware itself) efficiency on my M1 Mac. Does this actually exist? I apologise in advance as I know this isn’t the place to ask, but there’s clearly some expertise here. I would appreciate either a “keep dreaming for now”, or a link, or a hint. As someone who uses BitTorrent, this is a practical issue as well as one of my fetish for things working as efficiently as possible. Pretty crazy that this is a problem on the otherwise shockingly efficient Apple Silicon platform (but I get the need for driver security blah blah)

@zenczykowski
Copy link

@halfbrilliant Let's start off with a disclaimer: I'm a Linux Kernel / Android networking developer working on (among other things) tethering and NCM. I used to use macs, but that was quite a while ago, long before M1. The only Mac I currently have is a 2013-ish 27" iMac - and it is running Windows 10.

How do you want to plug it in? USB? Thunderbolt? don't care?
What speed do you need? 100mbps? gigabit? 2.5gbps? 5gbps? 10gbps? more?

In general none of the offloads are truly required for decent performance at 'just' low multi-gigabit speeds.
Sure, things like checksum offload and TSO are certainly useful, but they're only really needed at truly high speeds, and not at what mortals have available for internet access (yeah even 10gbps isn't really impressive nowadays, in a datacenter environment one can hit ~100gbps on a single tcp stream).

Additionally offloads are notoriously buggy (usually it's driver problems, sometimes it's a hardware or firmware issue)... for example the aforementioned iMac running Win10 has to have TSO disabled on the wired gigabit ethernet port, or tcp upload transfer is garbage (<20mbps) and needs to have transmit checksum offload disabled or (bridged) WSL fails to DHCP. I'm guessing these are 'just' software bugs (the latter in Window's WSL/bridge implementation)... but all I can do is disable the offloads to make things work.

NCM (which in the current spec has no offloads whatsoever) could do ~3.5gbps between a Linux laptop and a Pixel 6 Android phone (around 3 years ago when I worked on this). With a little optimization it could hit 7gbps.

The only true requirement is that the driver is not in userspace (copying all the data back and forth across the kernel/userspace divide is extremely cpu wasteful). This 'userspace driver' issue is apparently what the issue is with performance on Macs.

Personally I'd recommend a 2.5gbps USB-C dongle from StarTech (that should either use Mac's built in generic NCM driver, or an offload capable hardware specific driver). I've had good experiences with them, but there's usually cheaper variants available out there...

(Side note: don't bother with 5gbps Ethernet USB dongles, I'm not aware of anything that can go past ~3.45gbps due to usb3.0 limitations [USB3 is 5gbps, but it's 8b10b coded, which means it's really 4gbps usable, and there's further protocol overheads]. All currently [well at least ~2 years ago] available usb-ethernet converter chips are just usb3.0, so the dongles are expensive and run hot)

@totoCZ
Copy link

totoCZ commented May 2, 2024

As many pointed out, by default, MacOS will use the com.apple.DriverKit.AppleUserECM driver for any Ethernet port passed through USB using the Realtek 8156 chipset. This Apple supplied driver limits the overall speed of Ethernet connection through USB/Thundnerbolt to ~400 Mbps for some reason

I am running the Apple-bought Belkin with this driver and can hit over 900 Mbit.

What hasn't worked is a Vention hub with NCM (ASIX chipset). It simply negotiates 100Mbps and can't be changed, that one is a complete failure.

@halfbrilliant
Copy link

halfbrilliant commented May 2, 2024

@zenczykowski Thanks very much for that, you’ve refined and clarified my understanding quite a bit. I’ve been about to pull the plug on a 2.5gbps USB-C adapter (I have no 2.5gbps hardware, well, apart from the other 2.5gbps dongle I bought that ended up using far too much CPU when there were lots of packets flying around to be acceptable). But then I saw someone say that the only “true” offloading one would be within the expensive kind of Thunderbolt dock (i.e. that has its own power supply and starts around £200/$200).

Are you saying that the Startech dongles (I prefer 2.5gbps because big number better, although I understand (oh how I understand) the overhead issues with USB, so unless a 5gbps dongle was Thunderbolt I’d steer clear for now) won’t cause a silly amount of CPU usage during a heavy torrenting session? If I may restate my wildest desires more flexibly/plainly: I don’t care whether it connects via USB or Thunderbolt, but a USB-C connection is preferred (but I do have adapters for both ways). I just don’t want the CPU usage to be more than e.g. watching a 4K 10bit video - I know that is being offloaded and that’s why the CPU usage is so low, but that’s kind of the point and - call me spoiled - that’s how I remember Ethernet connections behaving on my old Macs, my old PCs, etc. Certainly my 2012 MacBook Pro (non Retina, still going strong as my always on Synthogy Ivory 2 piano station) has a built in Ethernet port that does not use 30-40% CPU under heavy packet load (I am a dumb dumb, but something tells me it’s more the amount of packets rather than large packets, but something in my left shin is telling me that I just said a stupid thing)

Obviously the less it costs the better, but I would much much much rather pay twice as much for something and have efficiency and reliability.

Thank you very much for responding, I know I am by no means entitled to anybody’s assistance, and if it’s more appropriate to do this sort of thing over PM or another forum please let me know. Jungle is massive

@zenczykowski
Copy link

Perhaps first some background.

There's a lot of USB Ethernet dongles available on the market. This makes it seem like there's a lot of choice. This isn't actually really the case. In practice these dongles are very thin wrappers around a USB-Ethernet converter/controller chip. Basically you have a chip, you have build & connector quality and how well the case can get rid of any chip generated heat (mostly matters for >1gbps speeds) - that's pretty much it. The only component that really truly matters (for most intents and purposes) is the chip (and technically the firmware/eeprom on it). There's actually very few of these, especially if you're talking about >1gbps speeds. Stuff might have changed, but there used to be just a single aquantia (since bought by marvell) chip capable of 5gbps ethernet, and two chips (one from aquantia, one from realtek) capable of 2.5gbps ethernet. There's a bit more choice with 1gbps, and more of a smattering with 100mbps.
[though note there is some extra variability due to chip revisions, and the firmware and other programming on the eeprom]

The chip has two 'sides'. One is the ethernet side, this is what 'gigabit' in a gigabit usb ethernet dongle refers to: the chip is capable of supporting gigabit ethernet speeds (and note: gbps ethernet is full duplex: you can read and write a gigabit at the same time). But since these are converter chips, there's also the USB side, which also has a max speed. This speed is often lower than the ethernet speed. There are plenty of 'gigabit ethernet usb dongles' that are only USB2.0 (theoretical 480mbps half duplex, which in practice is much lower, USB2 protocol efficiency is pretty terrible). This is why it's not rare for a 'gigabit' usb dongle to only be able to do ~400 mbps. Or why the '5 gbps ethernet' dongles max out around 3.5gbps.

USB naming is an utter mess. The original USB3.0 (superspeed) can only do 5gbps at 8b10b coding, which gives a data rate of 4gbps, and protocol overhead cuts it down further. USB3.1 (technically USB3.1 Gen2 superspeed+) can do 10gbps on short (<1m ~3ft) cables - and this finally uses a decent coding: 128b132b, so it can actually do 9.7gbps data rate (protocol overhead will still cut it down a bit). Yeah: 10gbps usb3 is ~2.4x faster than 5gbps usb3... But, I'm not aware of any usb/ethernet converter chip that is actually superspeed+ capable.

Another thing worth pointing out: a USB3 cable carries USB3 signaling on different wires than USB2/USB1.1/USB1. This means you can have a cable (or connector) which works for USB3 but doesn't work for USB2 (or the reverse, or is flaky and works sometimes...). This is even worse with USB-C cables, where there's multiple possible paths, multiple connector orientations, and some cables cheap out and don't include the USB3 wires at all, etc. ie. you can somewhat theoretically end up with a USB-C to USB-C cable that only works in one of 8 orientations (which end of the cable goes into which device, plus orientation of both connectors)... You can also end up with similar problems with USB-C ports (half broken, only works in one orientation), or device/dongle attached USB cables...

Furthermore 'gigabit ethernet' is referring to the bit-rate on the wire, but there's some framing overhead, which means that at the standard (internet max) mtu of 1500 bytes, a normal ipv4/tcp stream can only fit 1500 - 20 ipv4 header - 20 tcp header - 12 tcp timestamp options = 1448 payload bytes. Additionally Ethernet will prefix this with an 8 byte preamble, 14 byte ethernet header, and postfix this with a 4 byte CRC and 12 byte interframe gap. This means 1448 payload requires transmitting 1538 bytes. This in turn means 'gigabit' can transfer 1'000'000'000 bits / 8 bits per byte / 1538 bytes per frame = ~81274 packet per second, at 1448 payload bytes per second, that's ~117685305 bytes/s or ~112.2 MiB/s (which is 112.2*8= 897.6 mebibits/s)

The main benefit of 2.5gbps dongles is that (a) it's more future proof (b) you're less likely to run into garbage, simply because there's a fair bit less choice and these are still mostly premium (the run on the bottom of the barrel hasn't quite happened yet). There are plenty of good 'just' gigabit USB3 dongles on the market that can do bidirectional full gigabit. But there are also tons of bad ones.... Unfortunately a lot of the otherwise good ones, use the realtek chip with no native arm mac driver, that ends up using the dreaded low-performance AppleUserECM driver (side note: the terribly low performance of this hardware agnostic driver is entirely Apple's fault, but I'm guessing they [like me] would just prefer everything moves over to NCM). It's my understanding that an NCM spec revision to add some offload capabilities (presumably checksum and tso) is in the works.

Another comment: a lot of USB controllers (the chip built in to the desktop or laptop) in general leave quite a bit to be desired. Many of them for example don't support scatter gather (meaning all data has to be in a linear memory buffer with no page fragmentation), or even if they do support it, they support it poorly enough, that it's still faster if you linearize all data first (by copying it on the cpu). These aren't fundamental limitations of the USB protocol, but more actual implementation details... Networking happens to be one of those cases where the native network packet size (1500) and the native USB3 packet size (1024 or multiples there of, like 16384) are a very poor match, and result in this being particularly problematic. This is basically why native PCI networking is so much better. You can somewhat fix this by increasing network mtu size - but that doesn't help with internet bound traffic.

Are you saying that the Startech dongles ... won’t cause a silly amount of CPU usage during a heavy torrenting session?

I don't actually have the mac hardware to test this, but I would assume it'll be sufficient... Though do note it is still USB and not PCI (which is I believe what Thunderbolt adapters end up using) so you'll likely still have the linearization problem, and it's [presumably?] offload-less NCM rather than some checksum/tso offload capable native driver (note: tso can also mitigate some of the linearization/scatter gather problems...). Hard to say whether you'll consider this acceptable or not (I guess by it on Amazon, test it, report, and possibly return it?).
I'm not sure what native csum/tso capable usb3 >=gigabit ethernet dongle drivers an arm mac even has (both included by Apple, and whether any vendors actually provide native arm mac drivers). If you could find a dongle which uses such a native driver, you'd probably be happier (but I think Apple has been trying to prevent non-Apple kernel extensions, so it's possible such don't even exist any more??).

I do know on Linux we do have both the NCM generic driver and native drivers for these (r8156 I believe) dongles, but unfortunately I'm on vacation and left my pile of dongles at home so can't actually test the performance difference.

In general you are absolutely correct that large packets are easier to handle then small packets. Well, that's of course not true when phrased that way. The point is that a 'gigabit' is 81274 pps at 1500 mtu, but that same 'gigabit' can also deliver small packets. For example IPv4/TCP SYN will likely be not much larger then the ethernet minimum size of 46 bytes. This means you can get 1'000'000'000 / 8 / (8+14+46+4+12) which can give you 1'488'095 pps. So you have ~18.3 times more pps, and the packet is nowhere near 18 times cheaper to process: per packet processing overhead is huge (for example: firewall overhead is basically entirely per packet, as is figuring out which application socket a packet is bound for). Side note: small packets get no benefit from TSO (which is about offloading packet splitting to the nic, obviously no need for that if the packets are < mtu), and get virtually no benefit from checksum offload (which is mostly about checksumming the payload, of which there may be none). Perhaps to rephrase that: checksum offload makes the per-byte-of-payload overhead cheaper, but doesn't make per-packet overhead any better. TSO (and it's reverse on receive) actually reduces the number of packets one must send (or receive) and is thus a big win. On Linux (which I'm very familiar with) even for non-TSO capable hardware the stack jumps through hoops to basically do software TSO (so called GSO, and the reverse GRO) - this gets the majority of the benefit of less packets (in the firewall for example) without the need for hardware. I'm afraid I have absolutely no idea how optimized the network stack is on Apple. There's a reason that Linux dominates all sort of network/server environments...

@gdob
Copy link

gdob commented Jul 28, 2024

FWIW, on a MacBook Air M1 I experienced the same symptoms as mentioned in this thread using a Dell DA310 dock with a Realtek 8153 chipset. I found out there were firmware updates available for the dock on the official Dell website, so using a Windows machine I updated the firmware on the dock and since then I haven’t had any trouble using it (that’s full gigabit speeds and no random disconnects). I’m just putting this out there in case anyone finds it useful.

Cheers, and thanks everybody for the useful information already available here.

@aurejac
Copy link

aurejac commented Aug 17, 2024

Actual link to download the driver is now : https://www.realtek.com/Download/List?cate_id=585

@amitosdev
Copy link

Can anyone please recommend a USB-C to 2.5 Gbps Ethernet adapter that delivers full-speed performance on a MacBook M3?

@totoCZ
Copy link

totoCZ commented Oct 7, 2024

I think at this point the only safe choice is whatever apple store sells. But they don't sell 2.5G. Maybe try Belkin, it's their preferred brand.

@moonshiner
Copy link

I broke down and a Caldigit TS-4 Hub after buying every USB-C 2.5Gb Ethernet connector I could find and having them fail.
The Caldigit is ugh expensive but it is rock solid in speed/performance. YMMV

@ThePhoenix576
Copy link

Can anyone please recommend a USB-C to 2.5 Gbps Ethernet adapter that delivers full-speed performance on a MacBook M3?

I use an M1 MacBook and so far i have used this and so far it looks to be stable. It uses NCM on the Mac and so far with iperf3 i can confirm that it will saturate the gigabit up and down. Model : CM275 . The one i've got is from December 2023
image
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment