RTL8192CU and Linux 3.13.10

By Henry, on April 21st, 2014

Hardware: TP-Link TL-WN823N v1.1

Status: As of kernel 3.13.10, the in-tree rtl8192cu driver (in drivers/net/wireless/rtlwifi) is still broken. It will work and connect, but will silently disconnect after some time (and light traffic?). There is also some packet loss (around 1%).

Debugging notes

I don’t have much understanding of the Linux 802.11 drivers or Realtek chips to understand what’s going on. The following are some observations of the debug output around the time the connection is lost.

Looking at the debug messages when loading rtl8192cu with debug=5, the only messages that correlate with the moment the connection drops appears to be messages from rtl92c_dm_write_dig(). In the following messages, the failure occurred at 12:04:08 +/- 0.5 seconds. cur_igvalue is fairly stable around 0x20 until just before failure, after which it steadily increases to around 0x2a. Notice also that dm_digitable->large_fa_hit (second-last parameter in the list of “dig values”) becomes 1 a few seconds before failure, corresponding to a “false alarm” cnt_all greater than 0x2710 (10000).

My guess is that rtl92c_dm_write_dig() is being called from rtl92c_dm_ctrl_initgain_by_rssi (rtlwifi/rtl8192c/dm_common.c). Inside there, digtable->large_fa_hit seems to be counting instances (two-second periods?) where there are more than 10000 “false alarm” cnt_all (whatever that is), giving it three chances before setting some 2-hour timer (line 358). The logic around line 365 doesn’t look quite right for large_fa_hit greater than 0 but less than 3, because large_fa_hit never decreases until it reaches 3 and a two-hour timeout, but some digtable->forbidden_igi updates get turned off when large_fa_hit is non-zero. However, the Realtek vendor driver also has the same code, so this may not be the direct cause of the problem.

Perhaps a better question is why the “false alarm” count is suddenly so high (is this some kind of error counter?). Why is it called “false alarm”? Hmm… this looks familiar: http://www.google.com/patents/US20130308731

16 comments to RTL8192CU and Linux 3.13.10

Coming across your article cheered me up enormously. Rather than rant about the rtl8192cu support on linux, you seem to want to really get to the bottom of what’s wrong with it.

I’ve struggled for a couple of years to get this thing to work. The Realtek driver worked fine till I stopped being able to build it. (I’m now on kernel 3.14.4 under fedora.) Then the standard linux driver amazingly seemed to work for a bit with an old wireless router I had. It simply won’t work with a new router, however I configure things. The networking seems to be perfectly set up, with all the right IP addresses and gateways and routing. But unless I run a perpetual 1-a-second ping against the router, within seconds the thing dies, and I have to ifdown it, ifup it, and immediately start the ping. (Then, it seems to work fine, and indeed seems to function rather well.)

I wish I could help. Its been over 3 decades since I worked in system software. But I’m just about narked enough to try to get my head around the bloody driver.

Have you any hypotheses about why the thing works providing there’s a perpetual ping (in *or* out, BTW)?

[I might mention that although the dongle and the router are quite close in the same room, for marital reasons they’re also quite close to a phone base-station, so noise may be an issue. OTOH, the situation was even worse with my old router, with which the dongle worked without special measures.]

I’m not really looking for tips or configuration tweaks. This thing has consumed, end-to-end weeks of my time, and I guess the same goes for maybe a hundred thousand other people. What a waste of human life. It’s time to get to the bottom of it.

Did you try compiling with the 8192-fixes changes? That worked for me in 3.13, which hopefully isn’t too different from 3.14.

I have no hypothesis about why perpetual ping keeps the connection going. That actually wasn’t enough for me.

It’s actually a little strange because the code is quite similar between the vendor driver and the kernel driver. I read through some of the functions and they’re actually identical code with different formatting (to conform with Kernel code styles, I suppose). The drivers are subtly different somewhere, but not in the parts that I read though and could understand.

Well, I haven’t yet, partly because my (fedora19) distribution uses .rpms rather than whatever Ubuntu uses. But I’ve just now cloned the git repository, and it might not be beyond me to figure out what needs to be done. Certainly worth a try. I did something similar on fedora (applying patches from somewhere) till about a year(?) ago when the linux driver started to work for me with the router I was using at the time. (Probably by the skin on its teeth…)

I’ll if I can get anywhere with what’s in rtl8192cu-fixes. A quick google tells me ” DKMS supports both the RPM and DEB package formats out-of-the-box” so it may be easier than I thought.

I’m using Mageia, so it’s also RPM based. In my case, I just compiled it without DKMS or packaging it as an RPM, so package management didn’t get involved. (Though without DKMS, you’d have to manually recompile after every kernel upgrade)

If I remember correctly, it was as simple as running make to build 8192cu.ko, copying that into /lib/modules/<kernel version>/drivers/net/wireless, running depmod -a, and blacklisting rtl8192cu.

Thanks! By the time you wrote that I’d installed dkms and did what the README.md told me to do. I’m not sure exactly what went on but it built me a new initramfs and heaven knows what else. The new module turned up in /lib/modules/3.14.5-100.fc19.i686/extra/8192cu.ko. After depmod -a, and blacklisting the old module, the system booted fine, though sadly with no wireless. In a way I wish I’d not involved dkms.

I’m sure it’s something trivial, but someone else needs to use that machine for a while. The old initramfs was preserved, and using it I booted back to the original situation.
I’ll investigate later on this evening.

My first observation is that the ping times to the machine are now about 5ms (with the occasional 100ms), whereas with the “native” driver, the times were about 1ms (with the occassional 20ms). (But now I don’t need pings to keep the machine on the air.)

Also the new driver has a lot of (inscrutable!) parameters (37), whereas the native one had only 2 (swenc and debug).

Glad to hear it worked 🙂 Given how dkms did manage to build a .ko, it probably would have worked too, if 8192cu weren’t blacklisted…

I think the ping times are a lot higher due to power management. It’s particularly noticeable when pinging from another machine. It’s typically 70-90ms for me. You can tell it’s power management because if you ping it at a higher packet rate (say, 10 per second or more), the ping time drops to just under 1ms. The vendor driver package has documentation about what it does: (documentation/HowTo_enable_the_power_saving_functionality.pdf). The device wakes up at beacon intervals (typically 102.4ms?) to check for traffic when in sleep mode.

I suppose eventually these will get patched. Frankly I can’t remember the rigmarole to make corrections myself and rebuild the kernel.

To me it was interesting to read that the first bug was found using some tool (cppcheck) doing a static analysis of the code. Maybe we’d all get more of lives back if it was routine to use such tools.

I expect there are several bugs in the driver, and fixing one may only make others worse.

BTW, I switched back to using the native driver (with a perpetual ping). At one point I noticed that my wireless device seemed to be associated without any authentication, which ought to have been utterly impossible, for several reasons….

I’ve been fighting this problem all day. I am using Arch Linux on a Raspberry Pi B+ with a no-name b/g/n USB 2.0 wifi adapter I bought on eBay which uses the Realtek RTL8192cu chip.

I use wifi-menu to scan and connect to my home network and it seems to work fine, but after a short period of inactivity the wifi adapter stops responding, to inbound pings for example, or any other inbound traffic. If I do something outbound, ping for example, it comes back to life until more inactivity. I found that I could keep it working by running a neverending ping with a 5 second interval (I was pinging out from the Pi to another host on my network but seems like either direction would have worked).

It seemed like some kind of power saving feature messing us up.

Anyway, I didn’t want to have the hokey ping running all the time and that got me googling and that eventually lead me here.

I am not much of a UNIX/Linux guy so the prospect of compiling the kernel and/or “kernel modules” was daunting and seemed like a huge detour from what I am actually working on. I was just going to switch to a different wifi dongle when I found this workaround.

Then rebooted, and no more problem! THANK YOU, HENRY AND PETER! I’ve had an ssh session open all night and the connection is still alive. Previously it could not survive 5 minutes.

So it was not necessary for me to build a KO driver file or build the “latest” kernel (I did not want to do this because of comments that it would be “less stable” – my project needs to run unattended for long periods of time).

and then rebooted and it would have fixed the problem, or at least implemented the workaround (I don’t actually care about the power saving junk).

I’m just posting this for any other noobs like me who are not comfortable with all the detours in Linux, i.e. I just wanted to use a wifi dongle and the next thing you know I have to build this and that and it requires some additional package and that package requires three more packages but I really should use a cross-compile to “save time” (LOL) and then the repository is down and then I also need to make a “simple” configuration change but the change is obscured by having to learn the intricacies of the configuration utility for THIS particular distribution, etc etc etc.

It is a lot of fun, though, when you finally get something to work and learn a new trick. Thank God for search engines and all the helpful people on the Internet.

Hey, thanks for this. I bought a couple of monoprice USB/wifi dongles this week and have been suffering intermittent connections on a little single board computer I’m sending weather station data from. It’ll go OK for an hour or so, then drop out for an hour, re-connect. The chip is an Realtek 8192cu. I’ll try the ping method for the moment. I also have an old thinkpad T42 running xubuntu 14, I thought it was working OK on it, but what was I doing to check? Continual pinging of something!

I’m no linux expert at all but will be happy to report how things work for me here and if I get really ambitious will try to build your solution from github. Trying to get my startup company going at the moment 😉

Oh, hey, FWIW, these data give you an idea of the on/off nature of my connection. You can see where the data were being transmitted, and not. Very regular, at least…and it was able to re-connect regularly. Hmm.