Tags
8192cu, Raspberry Pi, RPi, USB, WiFi
This is a followup to my earlier post about configuring a Raspberry Pi for headless operation over WiFi. Since configuring my RPi, I’ve noticed that it will occasionally drop its WiFi connection after several hours. Since the RPi is headless, I’m fairly dependent on that network connection to interact with it at all. It turns out I’m not alone, and that there appears to be an easy fix. Read on for the details.
Why WiFi a Pi?
Like many users, I want to locate my RPi in a place where an electric outlet is available, but a network cable drop is not practical. The obvious solution is WiFi via USB. Since the RPi model B+ has four host ports, using a WiFi USB dongle doesn’t consume too many resources.
I bought this dongle from Adafruit mostly because I also bought the RPi from them in the same order, they were pretty clear about driver compatibility, and the price was really good.
As I documented in the earlier post, it was straightforward to get the WiFi operational, with just a little extra trickiness caused by me being stubborn about not booting to a desktop where a GUI tool could have written the configuration files for me.
Problem? What Problem?
I’ve been using that RPi for my ongoing series of posts about using the SPLear with an RPi, and often used the WiFi since it is configured. Since I no longer have a console serial port (that UART is now connected to the SPLear) whatever network I happen to be using is my only way in to the RPi.
But on several occasions where I’ve left it running a test and walked away for several hours, the network has unexpectedly gone offline.
Google Knows Everything!
I was expecting this to be a tough issue to resolve, since search terms like “Raspberry Pi”, “WiFi”, and “dropped” have many millions of hits each. Amazingly, when used together, they actually produced hits on many blog posts discussing variations on the same problem I was seeing. A top hit was to this article at Adafruit which is part of their basic education on the RPi, but which contains as an aside a fix to this very problem.
This WiFi adapter is based on a popular chip from Realtek, the 8192cu. Many inexpensive WiFi adapters are based on this chip, and it has had Linux kernel support for some time as a result. It would ordinarily seem like a safe choice. Like most modern Linux devices, its driver is loaded when needed as a “module”, and has a number of options or parameters that can be adjusted as needed.
It would appear that there is an issue with the 8192cu module’s handling of a power saving feature of the chip, when used in an RPi. The module distributed with Raspbian has this feature enabled. The consensus of the internet is that is a mistake in this platform.
The Fix is In!
Fortunately you don’t have to recompile the kernel or even the 8192cu module to fix this. You just need to create a file named /etc/modprobe.d/8192cu.conf
and give it this content:
# Disable power saving options 8192cu rtw_power_mgnt=0 rtw_enusbss=1 rtw_ips_mode=1
Be sure to edit that file as root, Adafruit suggests sudo nano /etc/modprobe.d/8192cu.conf
since the nano
editor is gentle for newcomers. I’ve been hanging around Unix-like systems for too long, and personally prefer vi
. But choice of text editor on Unix is a very personal thing, so don’t feel pressured to try vi
….
Since I made this change (and rebooted, perforce by taking the RPi home with me) it stayed connected to my home WiFi for at least 12 hours without dropping, and 7.5 hours without any user interaction.
What Did That Do?
When a module loads, the system looks in the folder /etc/modprobe.d
for a file that mentions the module. There is a strong convention that files in that folder be named for the module they are configuring, but the kernel is unaware of that, and simply searches *.conf
.
The file we created has a line that begins options 8192cu
. That identifies the module whose options we want to set. The 8192cu module has many options, which can be listed:
pi@treepi ~ $ ls /sys/module/8192cu/parameters/
if2name rtw_ht_enable rtw_network_mode
ifname rtw_hwpdn_mode rtw_notch_filter
rtw_80211d rtw_hwpwrp_detect rtw_power_mgnt
rtw_ampdu_amsdu rtw_hw_wps_pbc rtw_rf_config
rtw_ampdu_enable rtw_initmac rtw_rfintfs
rtw_antdiv_cfg rtw_ips_mode rtw_rx_stbc
rtw_busy_thresh rtw_lbkmode rtw_special_rf_path
rtw_cbw40_enable rtw_low_power rtw_vcs_type
rtw_channel rtw_lowrate_two_xmit rtw_vrtl_carrier_sense
rtw_channel_plan rtw_mac_phy_mode rtw_wifi_spec
rtw_chip_version rtw_max_roaming_times rtw_wmm_enable
rtw_enusbss rtw_mc2u_disable
rtw_force_iol rtw_mp_mode
As is typical, there doesn’t actually seem to be any readily accessible documentation on what these options do.
That said, the default value for rtw_power_mgnt
was 1. Setting it to 0 apparently skips the power saving logic and leaves the power set to active all the time. The value is selected from this enum
:
enum Power_Mgnt { PS_MODE_ACTIVE = 0 , PS_MODE_MIN , PS_MODE_MAX , PS_MODE_DTIM , PS_MODE_VOIP , PS_MODE_UAPSD_WMM , PS_MODE_UAPSD , PS_MODE_IBSS , PS_MODE_WWLAN , PM_Radio_Off , PM_Card_Disable , PS_MODE_NUM };
The default value for rtw_enusbss
is 0. From the source, it can be 0 for “disabled” or 1 for “enabled. Other than it being heavily used in the power management code, it is unclear what this option actually controls. Google suggests that “USB SS” would refer to USB 3.0 SuperSpeed, but it isn’t at all obvious how a WiFi driver would care whether the USB connection was in SuperSpeed mode or not.
The default value for rtw_ips_mode
is 1, but from the source code it could have been 0, 1, or 2 depending on what options were configured when the module was built. Setting it to 1 explicitly does no harm. It would be a value from this enum
:
enum { // for ips_mode IPS_NONE=0, IPS_NORMAL, IPS_LEVEL_2, };
It would be nice if there actually was some documentation on this other than the raw source code. Luckily, this recipe seems to work for me, and I can simply add my voice to the chorus observing that there was a problem that can be patched without fully understanding the issue.
Remember kids, if you have a project involving embedded systems, micro-controllers, electronics design, audio, video, or more we can help. Check out our main site and call or email us with your needs. No project is too small!
+1 626 303-1602
Cheshire Engineering Corp.
120 W Olive Ave
Monrovia, CA 91016
(Written with StackEdit.)
Reblogged this on Dinesh Ram Kali..
LikeLike