morrownr / 88x2bu-20210702

Linux Driver for USB WiFi Adapters that are based on the RTL8812BU and RTL8822BU Chipsets - v5.13.1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Please document difference to mainline driver

teletypo opened this issue · comments

I read that the 88x2bu driver is now in the mainline kernel, but apparently there's still some differences. In e.g. #195, @morrownr says

FYI: There is an in-kernel driver for your adapter these days if you are using kernel 6.4 or later. You would have to try it to see if it meets your needs.

Can somebody please document the differences to e.g. linux 6.7? Looking at the commits in this repo, I see mostly fixes to building and installing, but fewer relating to actual driver code. So I'm tempted to assume that this driver doesn't really have many fixes/features that the kernel driver does not have. But maybe there are some meaningful differences, like support for AP, MU-MIMO, speed, stability etc? Or maybe they use different firmware blobs?

Thanks!

commented

So I'm tempted to assume that this driver doesn't really have many fixes/features that the kernel driver does not have.

You should not make this assumption. The drivers are based on totally different source code. The in-kernel driver meets Linux Wireless Standards or it would not be in the kernel. That does not mean that all possible features are supported, it means that the features that are supported are done in accordance with the existing standards. This out-of-kernel driver is nowhere near compliant with Linux Wireless Standards making it hard to work on.

Or maybe they use different firmware blobs?

They do.

maybe there are some meaningful differences, like support for AP, MU-MIMO, speed, stability etc?

A few months ago, I tested an adapter with a rtl8812bu chipset with the in-kernel driver so as to get an idea of the status. I only had time for testing managed mode. What I found with kernel 6.4:

  • The in-kernel driver is stable. I did not see any drops with either band and tested for over 3 weeks using my primary work box.
  • This out-of-kernel driver is 10-15% faster but most average managed (client) mode users will not notice the difference.
  • Kernel upgrades are flawless with the in-kernel driver as should be expected.

I have added two adapters with rtl8812bu chipsets to the Plug and Play list. I put some warnings as users that are used to the Mediatek in-kernel drivers will likely be surprised. All Mediatek in-kernel driver are support by Mediatek kernel devs and we have access to them. Realtek did not develop the rtw88 usb support. Let's just say that Mediatek is all in and Realtek is not.

Can somebody please document the differences to e.g. linux 6.7?

I'm willing to help but I do not have the time to take on the project by myself. Wanna help?

@morrownr, thank you! I will test the in-kernel rtw88 for a 0bda:b82c Realtek Semiconductor Corp. 802.11ac NIC in 5.8GHz AP mode. If that's not happy I will test this driver, and report back either way.

I thought this and the in-kernel drivers had a common ancestry, but apparently that's not the case. Given that, to answer your question, no I don't want to document the differences between these two drivers.

@morrownr Thanks a lot for the comparison. Another difference I found with the rtw88 driver is that it does not support USB mode switching (USB 2.0 to 3.0 or vice versa). Because the device initializes in USB 2.0 mode, it won't switch to USB 3.0 with the in-kernel driver. Neither could I find any userspace tools (such as usb_modeswitch) that can perform the USB mode switch.

commented

@Smackd0wn

I have noticed this issue as well. At times, it will switch to usb3 but I need to take a better look at this. I think it may be a bugin the rtw88 driver.

Neither could I find any userspace tools (such as usb_modeswitch) that can perform the USB mode switch.

You won't find any switches. The modern stack, call it mac80211, is automated in this regard. I heavily use adapters based on the mt7612u and mt7921au chipsets that use in-kernel, mac80211, drivers. If I put an adapter with these usb3 capable chipsets in a port, the port is autodetected and usb is set accordingly. I've never seen it fail. If you want usb3, put the adapter in a usb3 port. and it you want usb2, put the adapter in a usb 2 port.

@morrownr

You won't find any switches. The modern stack, call it mac80211, is automated in this regard. I heavily use adapters based on the mt7612u and mt7921au chipsets that use in-kernel, mac80211, drivers. If I put an adapter with these usb3 capable chipsets in a port, the port is autodetected and usb is set accordingly. I've never seen it fail. If you want usb3, put the adapter in a usb3 port. and it you want usb2, put the adapter in a usb 2 port.

For regular USB 3 devices, such as thumb drives, yes, if you put it in a USB 3 port, it works as a USB 3 device. Probably Mediatek chips work like that as well. (Unfortunately I don't have any of those to test.)

But the Realtek 88x2bu does not work like that. It uses "smart switching" which means it always initializes in USB 2.0 mode when powered on. (At least my dongles do so.) The Realtek driver can let the device switch to USB 3.0 mode (or back to 2.0) by writing some registers:

enum halmac_ret_status
set_usb_mode_88xx(struct halmac_adapter *adapter, enum halmac_usb_mode mode)
{
u32 usb_tmp;
struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
enum halmac_usb_mode cur_mode;
cur_mode = (HALMAC_REG_R8(REG_SYS_CFG2 + 3) == 0x20) ?
HALMAC_USB_MODE_U3 : HALMAC_USB_MODE_U2;
/* check if HW supports usb2_usb3 switch */
usb_tmp = HALMAC_REG_R32(REG_PAD_CTRL2);
if (0 == (BIT_GET_USB23_SW_MODE_V1(usb_tmp) |
(usb_tmp & BIT_USB3_USB2_TRANSITION))) {
PLTFM_MSG_ERR("[ERR]u2/u3 switch\n");
return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
}
if (mode == cur_mode) {
PLTFM_MSG_ERR("[ERR]u2/u3 unchange\n");
return HALMAC_RET_USB_MODE_UNCHANGE;
}
/* Enable IO wrapper timeout */
if (adapter->chip_id == HALMAC_CHIP_ID_8822B ||
adapter->chip_id == HALMAC_CHIP_ID_8821C)
HALMAC_REG_W8_CLR(REG_SW_MDIO + 3, BIT(0));
usb_tmp &= ~(BIT_USB23_SW_MODE_V1(0x3));
if (mode == HALMAC_USB_MODE_U2)
HALMAC_REG_W32(REG_PAD_CTRL2,
usb_tmp |
BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
BIT_RSM_EN_V1);
else
HALMAC_REG_W32(REG_PAD_CTRL2,
usb_tmp |
BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
BIT_RSM_EN_V1);
HALMAC_REG_W8(REG_PAD_CTRL2 + 1, 4);
HALMAC_REG_W16_SET(REG_SYS_PW_CTRL, BIT_APFM_OFFMAC);
PLTFM_DELAY_US(1000);
HALMAC_REG_W32_SET(REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1);
return HALMAC_RET_SUCCESS;
}

I tested the 88x2bu driver (from this repository), with rtw_switch_usb_mode=1. Here is the kernel log:

08:43:53 kernel: usb 3-3: new high-speed USB device number 2 using xhci_hcd
08:43:53 kernel: usb 3-3: New USB device found, idVendor=0bda, idProduct=b812, bcdDevice= 2.10
08:43:53 kernel: usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
08:43:53 kernel: usb 3-3: Product: 802.11ac NIC
08:43:53 kernel: usb 3-3: Manufacturer: Realtek
08:43:53 kernel: usb 3-3: SerialNumber: 123456
08:43:54 kernel: 88x2bu: loading out-of-tree module taints kernel.
08:43:54 kernel: 88x2bu: module verification failed: signature and/or required key missing - tainting kernel
08:43:54 kernel: usb 3-3: USB disconnect, device number 2
08:43:54 kernel: rtl88x2bu 3-3:1.0: Runtime PM usage count underflow!
08:43:54 kernel: usbcore: registered new interface driver rtl88x2bu
08:43:55 kernel: usb 4-3: new SuperSpeed USB device number 2 using xhci_hcd
08:43:55 kernel: usb 4-3: New USB device found, idVendor=0bda, idProduct=b812, bcdDevice= 3.00
08:43:55 kernel: usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
08:43:55 kernel: usb 4-3: Product: 802.11ac NIC
08:43:55 kernel: usb 4-3: Manufacturer: Realtek
08:43:55 kernel: usb 4-3: SerialNumber: 123456

When plugged in, it apparently is a USB 2.0 only device, so the kernel found a new high-speed USB device. After the 88x2bu is loaded, and initialized the device (by uploading firmware, writing registers, etc.), the device "disconnected", then reappeared as a SuperSpeed device. That is the "smart switching".

Apparently the "smart switching" feature of 88x2bu is not very well documented. Some people thought the 88x2bu-based dongles are "fake" USB 3.0 devices because they always appear as USB 2.0 initially. I also found others asking about the mode switching, for example @scorpius2k1 from AUR.

I don't think the in-kernel rtw88 driver even support or attempt USB mode switching. mac80211 won't care either. Hence, with the rtw88 driver, the device will stay at USB 2.0.

I tested one more thing--after the Realtek 88x2bu driver made the device to switch to USB 3.0, I unloaded 88x2bu, and loaded rtw88 instead. Fortunately the device stayed at USB 3.0. and that the in-kernel driver works fine. I am not sure if the rtw88 driver will (or should) care about USB mode switch. I mean, for those dongles with Windows drivers onboard, the USB mode switch from CD-ROM to NIC is not Linux kernel's concern. Maybe a userspace program should make 88x2bu switch from USB 2.0 to 3.0 or vice versa.

commented

Apparently the "smart switching" feature of 88x2bu is not very well documented.

I've tried to help with the documentation. Run sudo sh edit-options.sh from the driver directory. There is documentation in that file and you will notice that the file also blacklists the in-kernel driver. This file is installed if you use sudo sh install-driver.sh to do the installation. The remove-driver.sh script will remove the file, including the blacklist.

Now, I'm not so sure I would call what this driver does as smart switching as it is a manual process.

Apparently the "smart switching" feature of 88x2bu is not very well documented.

I've tried to help with the documentation.

Yes, and thanks for that. But most people would expect a USB 3.0 device to work directly in USB 3.0 mode when they put it in a USB 3.0 port. They would not expect it to always initialize in USB 2.0 mode and USB 3.0 is only activated ("smart" or manually) by the driver. That part is not directly documented.

Now, I'm not so sure I would call what this driver does as smart switching as it is a manual process.

Either way, I have created a userspace program to manually perform the USB mode switching for users of the in-kernel (rtw88) driver:
https://github.com/Smackd0wn/rtw88_8822bu-usb3

@morrownr

I made some speed tests with my 8812bu cards (Comfast CF-812AC). All on Arch Linux (kernel 6.6.7), with iperf server running on an OpenWrt router (MT7621A/MT7603E/MT7612E), on channel 153 (5.765 GHz), VHT80. Tested with iperf -r. TX means USB wireless NIC to AP, while RX means AP to USB. Tests performed for several times, and the best is taken.

  1. With rtw88 driver (USB 2.0), TX 39 Mbps, RX 198 Mbps
  2. With rtw88 driver (manually switched to USB 3.0), same as 1
  3. With 88x2bu-20210702 driver (USB 2.0, rtw_switch_usb_mode=0), TX 98 Mbps, RX 250 Mbps.
  4. With 88x2bu-20210702 driver (USB 3.0, rtw_switch_usb_mode=1), same as 3

So the transmission from the USB card to AP is quite poor with rtw88, compared to 88x2bu.

In comparison, under the same testing condition, my 8821cu cards (Comfast CF-813B, about the same form factor as CF-812AC, both without long or external antennas) performed much better with rtw88 (TX 200Mbps, RX 250Mbps), or 8821cu-20210916 driver (about the same speed as rtw88).