# RTL8153 USB NIC help.



## cchorrell (Jun 7, 2018)

Hello all,

So I have been running FreeBSD and OPNsense as a VM's for some time now but due to changes I need to make internally I decided to repurpose an old portable to be the ONSense box, now I know this isn't the OPNsense forum but I believe my issue and question is more of a base system thing but I have posted this over at their forum as well.  
The portable has one built-in NIC that was properly identified and is working fine, but my USB RTL8153 has been identified as ue0 and it appears it cannot identify the media type.  I believe this to be the cause of the card acting as a 10Mbit NIC.  After some research I believe the correct driver to be ure, the FreeBSD man page states this is for the RTL8152, but the same driver in the OpenBSD man shows it is for both the RTL8152/RTL8153.  Both man pages shows the author of the driver to be the same person.

My issue right now is that after several days of internet research I am at a lose as how best to make OPNsense or FreeBSD use the ure driver for this NIC.  The farthest I have gotten is to use 'kldload if_ure' in the shell and I would appreciate any advise or resources that I could be pointed to so I can remedy this.

Thank you all for your time.


----------



## cchorrell (Jun 7, 2018)

Update on the above.  I now have the 'ure' driver loading as a kernel module on boot.  Now on to figure out how to force the hardware to use the driver, but so far I have not found any resources online to help, or at least ones that I understand.


----------



## SirDice (Jun 7, 2018)

cchorrell said:


> Now on to figure out how to force the hardware to use the driver


You can't force hardware to use a certain driver. The driver detects the hardware or not, not the other way around. This detection is mostly based on IDs read from the chipset (see the output from `pciconf -lv` for example). Realtek seems to have a nasty habit of changing their chip's designs without changing the IDs.


----------



## cchorrell (Jun 8, 2018)

SirDice said:


> You can't force hardware to use a certain driver. The driver detects the hardware or not, not the other way around. This detection is mostly based on IDs read from the chipset (see the output from `pciconf -lv` for example). Realtek seems to have a nasty habit of changing their chip's designs without changing the IDs.



Ok, well in my case I am connected to a USB controller on the PCI and the card appears as


```
ugen3.2: <Realtek USB 101001000 LAN> at usbus3, cfg=1 md=HOST spd=HIGH (480Mbps) pwr=ON (200mA)
```

The system then identified it as at ue0, but I could not find a man page for the ue driver.


```
ue0: <USB Ethernet> on cdce0
ue0: Ethernet address: a0:ce:c8:15:cd:2c
```

I identified the adapter as a RTL8153 after that and found out about the ure driver by searching man pages.  So I guess my next question is how could I go about having the ure driver detect this card as opposed to the ue driver?  Or is there no way to do that without rewriting both drivers?

Thanks for your reply.


----------



## Phishfry (Jun 8, 2018)

There is no need to load any driver. You have the interface ready to use.
You will need to declare if you want to assign a static IP to it or use DHCP in /etc/rc.conf
The setting for DHCP would look like this:
`ifconfig_ue0="DHCP"`
For a static IP you could use something like this:
`ifconfig_ue0="inet 192.168.11.111 netmask 255.255.255.0"`

Because this is an USB interface you might need to add a boot delay to allow for the interface to come up.
Many USB interfaces come up late, So you might need to use netwait.


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> There is no need to load any driver. You have the interface ready to use.
> You will need to declare if you want to assign a static IP to it or use DHCP in /etc/rc.conf
> The setting for DHCP would look like this:
> `ifconfig_ue0="DHCP"`
> ...




I have the ue0 confided and passing traffic, the issue with the ue driver is that it is only running at 10mbit/s.  The hardware, RTL8153 is 1Gbit/s, and unlike all other NIC's I have configured in any other flavor of UNIX or Linux it does not report anything for media.

For example, the onboard NVIDIA NIC shows media and active.

```
nfe0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=82008<VLAN_MTU,WOL_MAGIC,LINKSTATE>
    ether 58:b0:35:b3:21:72
    hwaddr 58:b0:35:b3:21:72
    inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
    inet6 fe80::1:1%nfe0 prefixlen 64 scopeid 0x1
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
```

but the RTL8153 doesn't report either, although it can pass traffic, but again at only 10Mbit

```
ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    ether a0:ce:c8:15:cd:2c
    hwaddr a0:ce:c8:15:cd:2c
    inet6 fe80::a2ce:c8ff:fe15:cd2c%ue0 prefixlen 64 scopeid 0x6
    inet 172.16.42.50 netmask 0xffffff00 broadcast 172.16.42.255
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
```

Normally I would have just looked up the man page for the ue driver but there doesn't seem to be one.  The ure driver shows it is for a RTL8152 in FreeBSD, but the OpenBSD man page for the same drivers says it supports both RTL8152 and RTL8153.  Both the FreeBSD and OpenBSD man page credits the same author, so my indention was to figure out a way for the ure driver to recognize the hardware so I could test.  Ultimately I do not care which driver as long as it is one that I can max out the USB bus for this NIC.


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> Where did you find that information?
> How about you post the output of `ifconfig`.



I have a iperf3 server/client running on both sides of the interface is how I determined the speed, not that it is actually reporting the media type. In my post above is the ifconfig output of both the onboard NIC (nfe0) and the RTL8153 USB NIC (ue0).  I'll post it again here.


```
# ifconfig
nfe0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=82008<VLAN_MTU,WOL_MAGIC,LINKSTATE>
    ether 58:b0:35:b3:21:72
    hwaddr 58:b0:35:b3:21:72
    inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
    inet6 fe80::1:1%nfe0 prefixlen 64 scopeid 0x1
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active

ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    ether a0:ce:c8:15:cd:2c
    hwaddr a0:ce:c8:15:cd:2c
    inet6 fe80::a2ce:c8ff:fe15:cd2c%ue0 prefixlen 64 scopeid 0x6
    inet 172.16.42.50 netmask 0xffffff00 broadcast 172.16.42.255
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
```


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> Something is up. I see no status: and it seems strange to me that the ipv6 line is before inet



Yeah I have never had this happen with a NIC, USB or PCI connected, on any flavor or *NIX.  With no media or status being reported it is strange.  Also I have never had a NIC load with a driver that has no man page.  As for the ipv6 that shows up ahead of the ipv4 address for me anytime I configure inet6 for local-link.


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> Is this a dhcp lease or are you using static IP here?
> Please post your /etc/rc.conf
> 
> You may just need to add netwait.
> How does it act when you hot plug it -versus bootup with the device?



Hot plugging identifies the card the same,

```
ue0: <USB Ethernet> on cdce0
ue0: Ethernet address: a0:ce:c8:15:cd:2c
```

I take it that likely means that netwait would have no change?

I can post my entire rc.conf if needed but it is quite large.


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> ue0 is sort of a master interface. You might find it on USB cellular modems or tethered cell phones.
> It is different than the pciconf interfaces.
> It does still use the VID and PID like SirDice was mentioning. Its just that PCI devices use a different file for their ID's.
> So it is a different subsystem.




I know we are several replies in, but to remind I am running OPNsense, based on FreeBSD-11.1.  I had posted this same thing over in their forums but so far they are just lurking it.  I then posted the same over here since OPNsense tries to maintain as much as FreeBSD as possible.


----------



## Phishfry (Jun 8, 2018)

cchorrell said:


> I take it that likely means that netwait would have no change?


If your ifconfig output looks the same then yes, save your time.
Post the full device details:
`usbconfig -u 3 -a 2 dump_device_desc`


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> If your ifconfig output looks the same then yes, save your time.
> Post the full device details:
> `usbconfig -u 3 -a 2 dump_device_desc`



As requested,

```
# usbconfig -u 3 -a 2 dump_device_desc
ugen3.2: <Realtek USB 101001000 LAN> at usbus3, cfg=1 md=HOST spd=HIGH (480Mbps) pwr=ON (200mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0210
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0040
  idVendor = 0x0bda
  idProduct = 0x8153
  bcdDevice = 0x3000
  iManufacturer = 0x0001  <Realtek>
  iProduct = 0x0002  <USB 10/100/1000 LAN>
  iSerialNumber = 0x0006  <000001>
  bNumConfigurations = 0x0002
```


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> Well HPS is the USB guru you would have to bug, if you didn't come here or OPN forum and their one man band.
> So I see it as trying to solve your problem before bugging a developer.
> It is against the forum rules but the guts of OPN are nearly identical in this case.
> 
> I am no USB expert and have run the course here. The VID and PID is supported in usbdevs.



Thank you Phishfry for your assistance, I really appreciate it.

I was researching this as much as possible first and seeing the low activity on the OPN forums, I hesitantly posted here since I had a feeling it wasn't strictly OPN related.

Forgive my ignorance, but is HPS the username of the USB guru on these forums or is it an acronym for a group?


----------



## Phishfry (Jun 8, 2018)

cchorrell said:


> bNumConfigurations = 0x0002


This output is the only thing i see that is unusual.
Usually you only see number of configurations on cellular modems. They allow for 2 configurations.

You could file a PR with the details. It might help the next guy with the problem.
Very generally here, Realtek is considered bad.
They have RT8111 chips that are OK and some newer ones that won't work well at all. Especially when loaded.
Intel interfaces on the other hand have always worked very well.

So there is no surprise that you are getting bad results with a Realtek device.
There are other gigabit USB ethernet devices that do work OK.


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> This output is the only thing i see that is unusual.
> Usually you only see number of configurations on cellular modems. They allow for 2 configurations.
> 
> You could file a PR with the details. It might help the next guy with the problem.
> ...




Realtek wasn't my first choice but after trying with a ASIX USB NIC and having poor performance in OPN, FreeBSD, and Debian 9 I decided to order the Realtek to test with.  But it would seem I am running out of USB NIC's to try with.  I even went so far as testing both USB NIC's in macOS and Win10 and the worked flawlessly, but when running OPN or FreeBSD as VM's using VirtualBox and bridging to the USB I could only max out at around 150mbit/s and it wasn't consistent.

I think I may file a PR tomorrow after I get some sleep and if it isn't considered inappropriate I may DM hps@ for assistance.

Thank you again for your help.


----------



## Phishfry (Jun 8, 2018)

Ahhhhhha

I found that I was right. bNumconfigs !!!!!
https://lists.freebsd.org/pipermail/freebsd-net/2015-June/042396.html

https://forums.freebsd.org/threads/rtl8153-ethernet-adapter-on-pfsense.57299/


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> Ahhhhhha
> 
> I found that I was right. bNumconfigs !!!!!
> 
> https://forums.freebsd.org/threads/rtl8153-ethernet-adapter-on-pfsense.57299/



I will read though that thread and the one linked in it now.  With a little luck this may do it!  At the very least I will report back here with my success or failure.


----------



## Phishfry (Jun 8, 2018)

I am not sure it will work for you, but it is the only thing I see that looks related.
The other user had no working device so I am unsure this is related.
Something is in the other configuration, I would think.
My general thought is there is ipv6 profile and a ipv4 profile, it is defaulting to ipv6 profile.


----------



## cchorrell (Jun 8, 2018)

Phishfry said:


> I am not sure it will work for you, but it is the only thing I see that looks related.
> The other user had no working device so I am unsure this is related.
> Something is in the other configuration, I would think.
> My general thought is there is ipv6 profile and a ipv4 profile, it is defaulting to ipv6 profile.



Well you are spot on, after reading though everything over there the good news is they are talking about the same USB NIC as mine but the bad news is theirs was booting up as configuration 0 and they needed to get it to configuration 1.  Mine is already booting that way. I would also be interested to know if they were running into the same issue I am after they solved their first problem.

I will looking to this idea of ipv6 profile vs ipv4 profile and I think I will also test out a fresh vanilla 11.1 install and maybe even try 12 or TrueOS to see if the same issue persist across them all.


----------



## SOUK (Dec 31, 2018)

I'm in the exact same boat as you with regards to that USB device in opnsense, did you ever manage to find a resolution?


----------



## yorch (Apr 12, 2020)

Exact same problem, I have a similar USB NIC with the same Realtek chipset, and it works with OPNSense, but the speed is awful. I've been using the exact same USB device as the WAN interface in linux (IPFire) for a few years and with great success, no speed issues. So something with the driver or configuration most likely.

SOUK, cchorrell, Did you figure it out?

Thanks


----------



## sh133 (Jan 1, 2021)

I have the exact same bandwidth issue, on a FreeBSD 12.1-RELEASE derivative (OPNSense 20.7), with a USB 3.0 C to Ethernet adapter which embeds a RTL8153 chip.
The adapter is supposed to reach 1Gb/s and offers some HW offloading, but tops to 91Mb/s and does not stand any HW offloading, on very decent hardware.
I could not stand such madness, so tried to understand more, and thought other users might find report useful.

*TL;DR*: _the "ure(4)" driver for RTL8153 in FreeBSD <= 12 is not able to do more than 91Mbits, by design, because of its USB communication methods. Changing adapter USB mode might get you more (by bypassing "ure" driver), but will hurt connection stability as a price. 13-CURRENT's "ure" driver has been rewritten and fixes this since Q4 2020. It's not simple, but feasible, to port 13-CURRENT rewritten "ure" to FreeBSD 12 (it involves kernel module code change, and kernel-land compilation), and results are not that good on my case (but it's way better than 91Mb/s)._

First according to Realtek specs on RTL8153(CG), the chip already embeds an USB controller (so situation should not vary much depending on adapter vendor), and offers 2 distinct USB configs: one that is supposed to run without any OS driver on some OSes ("CDC-ECM" mode, in short an "Internet connected device over USB"), and one that is exposing an Ethernet adapter and that needs drivers on OS-side (called "in-house"), and which is supposed to be able to reach better results. IMHO, the default USB config may depend on adapters vendors, and even OS. Mine was working as "in-house" by default, and offered better bandwidth in "CDC-ECM" mode (approx 300Mbits), but way worse stability. You can change default USB mode pretty easily with `usbconfig -d <X.Y USB device address> set_mode <0 or 1>`, and make that persistent with usb_quirk(4), as referenced earlier in this thread.

Then second, according to this FreeBSD news report on ure driver from 2020-09, and to put it simply, the actual "ure" driver in FreeBSD 12 and prior cannot do Gigabit because of the way it deals with USB communications. It has been rewritten, and is able to reach ~900Mb/s on FreeBSD 13-CURRENT according to author (and passing by, enabled CVE-2020-7464 vulnerability fix, which has been backported to FreeBSD 11 and 12). This rewriting however occurred at FreeBSD 13, using FreeBSD 13 kernel API, so cannot be directly compiled in FreeBSD 12 kernel tree. I managed to port rewritten code to FreeBSD 12.1-RELEASE, and compile "ure" so that it works in my OPNSense 20.7 environment (it's not an easy task for most users I guess); but FreeBSD is new to me, and this is kernel module code, so result is probably very nasty. I can now reach ~450Mb/s throughput with the same adapter, and the stability does not seem to be worse than before. I sent the code to ure rewriting author, in case he wants to check it and push it somewhere for FreeBSD 12.


----------



## Alex Ander (Apr 8, 2021)

sh133 said:


> I have the exact same bandwidth issue, on a FreeBSD 12.1-RELEASE derivative (OPNSense 20.7), with a USB 3.0 C to Ethernet adapter which embeds a RTL8153 chip. The adapter is supposed to reach 1Gb/s and offers some HW offloading, but tops to 91Mb/s and does not stand any HW offloading, on very decent hardware. I could not stand such madness, so tried to understand more, and thought other users might find report useful. *TL;DR*: _the "ure(4)" driver for RTL8153 in FreeBSD <= 12 is not able to do more than 91Mbits, by design, because of its USB communication methods. Changing adapter USB mode might get you more (by bypassing "ure" driver), but will hurt connection stability as a price. 13-CURRENT's "ure" driver has been rewritten and fixes this since Q4 2020. It's not simple, but feasible, to port 13-CURRENT rewritten "ure" to FreeBSD 12 (it involves kernel module code change, and kernel-land compilation), and results are not that good on my case (but it's way better than 91Mb/s)._ First according to Realtek specs on RTL8153(CG), the chip already embeds an USB controller (so situation should not vary much depending on adapter vendor), and offers 2 distinct USB configs: one that is supposed to run without any OS driver on some OSes ("CDC-ECM" mode, in short an "Internet connected device over USB"), and one that is exposing an Ethernet adapter and that needs drivers on OS-side (called "in-house"), and which is supposed to be able to reach better results. IMHO, the default USB config may depend on adapters vendors, and even OS. Mine was working as "in-house" by default, and offered better bandwidth in "CDC-ECM" mode (approx 300Mbits), but way worse stability. You can change default USB mode pretty easily with `usbconfig -d set_mode <0 or 1>`, and make that persistent with usb_quirk(4), as referenced earlier in this thread. Then second, according to this FreeBSD news report on ure driver from 2020-09, and to put it simply, the actual "ure" driver in FreeBSD 12 and prior cannot do Gigabit because of the way it deals with USB communications. It has been rewritten, and is able to reach ~900Mb/s on FreeBSD 13-CURRENT according to author (and passing by, enabled CVE-2020-7464 vulnerability fix, which has been backported to FreeBSD 11 and 12). This rewriting however occurred at FreeBSD 13, using FreeBSD 13 kernel API, so cannot be directly compiled in FreeBSD 12 kernel tree. I managed to port rewritten code to FreeBSD 12.1-RELEASE, and compile "ure" so that it works in my OPNSense 20.7 environment (it's not an easy task for most users I guess); but FreeBSD is new to me, and this is kernel module code, so result is probably very nasty. I can now reach ~450Mb/s throughput with the same adapter, and the stability does not seem to be worse than before. I sent the code to ure rewriting author, in case he wants to check it and push it somewhere for FreeBSD 12.



Hey there, sh133.

Could you share with us how you put the rewritten code to FreeBSD 12.1-RELEASE, and how you did compile it. Im interested in, have the same performance issue.
Or if too complicated, firstly, how to I execute the usbconfig to try first?

Thanks in advance,
Alex


----------



## Meridian (Apr 15, 2021)

I have purchased some Cable Matters USB 3 to gigabit Ethernet adapters and they are using the RTL8153 chipset as well.  Came across this thread after I noticed very slow speeds (3MB/s).  I have them connected to a laptop running OPNSense 21.1.4.  Here are the steps I took to get the new driver working:

Enable SSH in OPNSense and SSH to server
Go to the shell (option 8)
Create a new directory in your home directory:
`mkdir ure_new`

Change to new directory:
`cd ure_new`

Download the new ure driver files using curl:
`curl -o if_ure.c "https://svnweb.freebsd.org/base/head/sys/dev/usb/net/if_ure.c?revision=368801&view=co`
`curl -o if_urereg.h "https://svnweb.freebsd.org/base/head/sys/dev/usb/net/if_urereg.h?revision=365648&view=co`
`curl -o Makefile "https://svnweb.freebsd.org/base/head/sys/modules/usb/ure/Makefile?revision=365648&view=co"`

Copy the old drivers to your home directory to have as a backup:
`cp /usr/src/sys/dev/usb/net/if_ure.c $home`
`cp /usr/src/sys/dev/usb/net/if_urereg.h $home`
`cp /usr/src/sys/modules/usb/ure/Makefile $home`

Copy the new drivers to the source tree:
`cp if_ure.c /usr/src/sys/dev/usb/net/`
`cp if_urereg.h /usr/src/sys/dev/usb/net/`
`cp Makefile /usr/src/sys/modules/usb/ure/`

Run the first four commands here: https://github.com/opnsense/tools#setting-up-a-build-system
Use vi to make the following changes to ir_ure.c (Hopefully you don't have a device with one of the descriptors I had to remove.):
`vi /usr/src/sys/dev/usb/net/if_ure.c`


```
100,102d99
<       URE_DEV(LENOVO, TBT3LAN, 0),
<       URE_DEV(LENOVO, ONELINK, 0),
<       URE_DEV(LENOVO, USBCLAN, 0),
1153a1151
>       struct ifmultiaddr *ifma;
1172,1173c1170,1183
<       if_foreach_llmaddr(ifp, ure_hash_maddr, &hashes);
<
---
>       rxmode |= URE_RCR_AM;
>       if_maddr_rlock(ifp);
>       CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
>               if (ifma->ifma_addr->sa_family != AF_LINK)
>                       continue;
>               h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
>               ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
>               if (h < 32)
>                       hashes[0] |= (1 << h);
>               else
>                       hashes[1] |= (1 << (h - 32));
>       }
>
>       if_maddr_runlock(ifp);
```


In my case, I made an additional change to ethernet.h, but in retrospect I think it would have made more sense to do in if_ure.c.  By making the change in ethernet.h, it meant I had to remove the added function also from /usr/src/sys/dev/usb/net/if_smsc.c and /usr/src/sys/dev/usb/net/if_muge.c.  This is the function that was taken out of the driver and moved into ethernet.h.  Plunking it back into the new ure driver roughly where it was taken out of the old driver should be fine, but I haven't tested it.
Build the kernel:
`make kernel`

Make a backup of your current kernel:
`cp -a /boot/kernel $home/kernel.orig`

Copy the newly built kernel in:
`cp -a /usr/boot/kernelobj/usr/src/amd64.amd64/release/dist/kernel/boot/kernel/ /boot/kernel`

Reboot and enjoy much better speed!


----------



## TMA2day (May 20, 2021)

Meridian - a huge "Thank you" for documenting what you did above.  Using your information I was able to get a TP-Link USB ethernet adapter to pass traffic about 50% faster than before - from ~80 Mbps to ~120 Mbps (my current cap).​
For anyone else trying to do the steps, some notes about what I did to get things to work.

after enabling ssh, I also had to enable root ssh and password (probably could have created another user instead)
ran the "Run the first four commands here:" immediately after "Download the new ure driver files using curl:"  (the path/files didn't exist until I ran these)
Instead of four commands, I had to do five:
# pkg install git
# cd /usr
# git clone https://github.com/opnsense/tools
# cd tools
# make update

if you aren't familiar with the diff output, that's basically:
set number in vi so you can match the line numbers shown - I used two ssh sessions so I could view the original file while editing the new one
remove the three LENOVO related lines indicated
insert the struct line
remove the if_foreach_llmaddr line
insert the block starting with rxmode
while you're at it, insert this as well (mine is on lines 79-80)



#define ETHER_IS_ZERO(addr) \ (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) 




My new kernel was in a different location than Meridian's.  It was /usr/obj/usr/tools/config/21.1/OpenSSL:amd64/work/boot/kernel


----------

