Wednesday, November 15, 2017

Linux built-in driver fails for Edimax EW-7811Un [Realtek RTL8188CUS]

It seems that I have been struggling with this small piece of hardware for years; and it has been giving me surprises all the time.

Yes, I am talking I about this Wi-Fi dongle again:

Edimax EW-7811Un
While it still appears to be one of the best sellers on Amazon, a lot of people have had problems with it when using with Linux systems.

Recently the critical problem is the intermittent connection issue which occurs on a lot of Wi-Fi adapters including some of the RTL models. https://www.google.com/search?q=ubuntu+intermittent+wifi&ie=utf-8&oe=utf-8 (a lot of complaints are from Ubuntu users, likely because a good part of Linux desktop users are using Ubuntu).
If many years later when you click on this link you do not see any sense making posts, that means the problem is probably solved -- which would be great.

Long story short, I am not writing to provide a full solution to this problem, because there is already one: GitHub - pvaret/rtl8192cu-fixes: Realtek 8192 chipset driver, ported to kernel 3.11.
It has very straight forward installation instructions in the GitHub repo's `README.md` file; I have been using this fixed driver for a lot of Ubuntu 16.04 LTS PCs and it solves the problem like a charm.
For example, it works on my desktop PC which runs Ubuntu 16.04.3 LTS (GNU/Linux 4.10.0-38-generic x86_64).

However, this simple solution did not work immediately when I tried it with a CentOS 7 desktop using kernel version 3.10.0-693.5.2.el7.x86_64.
During installation I had several problems:
  1. After installation my `dmesg` shows:

    8192cu: loading out-of-tree module taints kernel. / 8192cu: module verification failed: signature and/or required key missing - tainting kernel
  2. Once I blacklist the built-in driver (rtl8192cu) as I usually do with Ubuntu 16.04 LTS, no new driver is loaded for my Wi-Fi dongle. The device completely disappears from NetworkManager. While it is still there if I do `ifconfig -a`, there does not seem to be a way that I can start it.
Here are some experiences on how I finally made it work:

First, the "tainting kernel" message does not matter -- as long as the driver is still loaded as a kernel module. You can check whether it is using `lsmod` -- it should appear as "8192cu".

Second, it does not really matter if you see "used = 0" for "8192cu" in `lsmod`, because that is also the case on my Ubuntu 16.04 LTS desktop.

Third, I still do not know how to make it work with NetworkManager. Instead, I turned to use `wpa-supplicant` directly. This tool is very fundamental, and does not allow you to switch Wi-Fi access points based on your need or in any graphical way; it fits in my needs perfectly but may not fit in yours.

The instructions to disable NetworkManager and configure the Wi-Fi dongle to work with `wpa-supplicant` directly is here: HowTos/Laptops/WpaSupplicant - CentOS Wiki.
Some of the instructions are outdated -- in `prepnet`, you should probably use `systemctl start messagebus` instead of calling it from `init.d`, for example.

Note that, if you do not want to disable NetworkManager completely, you can just set you specific Wi-Fi dongle to be "unmanaged" for it: configuration - How can I make NetworkManager ignore my wireless card? - Ask Ubuntu.

One more thing is, I found that when using wpa_supplicant, the default driver `nl80211` does not work with the fixed driver aforementioned. However, I succeeded with "wext". This can be changed in `/etc/sysconfig/wpa_supplicant` where there is a place for users to specify the driver to use. I changed its first two sections into:

# Use the flag "-i" before each of your interfaces, like so:
#  INTERFACES="-ieth1 -iwlan0"
INTERFACES="-iwlp0s26f7u1"

# Use the flag "-D" before each driver, like so:
#  DRIVERS="-Dwext"
DRIVERS="-Dwext"


Now I have been using this desktop for a day and have not noticed any intermittent connection issue so far, which used to happen every several minutes.
It appears it has been resolved.

In summary:
  1. Use the fixed driver (rtl8192cu-fixes).
  2. Disable NetworkManager (at least for the problematic device) and use wpa_supplicant.
  3. Config wpa_supplicant to use the "wext" driver.
Good luck :-)