Realtek RTL8188CUS USB WiFi Integration
Introduction
This white paper will show how to integrate the Realtek RTL8188CUS chipset found in the D-Link DWA-121 USB WiFi dongle with a LeopardBoard DM368. Although the process is given for a specific board and wifi adaptor, it is possible to translate it to others boards and wifi adaptors.
If you use the D-Link DWA-121 or some other dongle that has the RTL8188CUS chipset, the process will be very similar.
Using lsusb on a desktop machine, the D-Link DWA-121 is identified as (simplified):
2001:3308 D-Link System DWA-121 rev.A1 Realtek RTL8188CUS
The RTL8188CUS chipset is supported by the wireless Linux effort. They state every stable version should be compatible with every kernel >= 2.6.26 , so the latest (at the time of this writing Jan 18, 2013) compatibility tarball was used.
XXX not updated below this point yet
Driver integration
Create pristine driver tarball
# setup the kernel patch file cd $DEVDIR/kernel quilt new 8712u-driver.patch # extract the part of the zip file we need mkdir -p $DEVDIR/tmp cd $DEVDIR/tmp curl -f -L ftp://WebUser:Lc9FuH5r@207.232.93.28/cn/wlan/RTL819xSU_usb_linux_v2.6.6.0.20120405.zip > RTL819xSU_usb_linux_v2.6.6.0.20120405.zip unzip RTL819xSU_usb_linux_v2.6.6.0.20120405.zip cd rtl8712_8188_8191_8192SU_usb_linux_v2.6.6.0.20120405/driver tar -xzf rtl8712_8188_8191_8192SU_usb_linux_v2.6.6.0.20120405.tar.gz mv rtl8712_8188_8191_8192SU_usb_linux_v2.6.6.0.20120405 8712u # add the driver to the kernel tree mv 8712u $DEVDIR/kernel/linux-*/drivers/net/wireless cd $DEVDIR/kernel KER=`ls -d linux-*` # add driver files to patch file DRIVER_FILES=`find $KER/drivers/net/wireless/8712u -type f` mv $KER/drivers/net/wireless/8712u $KER/drivers/net/wireless/8712u.new echo $DRIVER_FILES | xargs quilt add mv $KER/drivers/net/wireless/8712u.new $KER/drivers/net/wireless/8712u quilt add $KER/drivers/net/wireless/Makefile $KER/drivers/net/wireless/Kconfig cd $KER/drivers/net/wireless echo 'obj-$(CONFIG_RTL8712U) += 8712u/' >> Makefile # replace endif # WLAN with line to source the 8712u driver sed -i.bak -e 's!^endif.*!source "drivers/net/wireless/8712u/Kconfig"!' Kconfig echo 'endif # WLAN' >> Kconfig quilt refresh
Create 2.6.32 backport tarball
The 2.6.32 kernel doesn't support pmksa or pmkids, so those features need to be included only for newer kernels.
Index: kernel/linux-2.6.32.17-psp03.01.01.39/drivers/net/wireless/8712u/os_dep/linux/ioctl_cfg80211.c =================================================================== --- kernel.orig/linux-2.6.32.17-psp03.01.01.39/drivers/net/wireless/8712u/os_dep/linux/ioctl_cfg80211.c 2012-11-27 10:37:26.465000634 -0700 +++ kernel/linux-2.6.32.17-psp03.01.01.39/drivers/net/wireless/8712u/os_dep/linux/ioctl_cfg80211.c 2012-11-27 10:39:44.100915436 -0700 @@ -1876,6 +1876,7 @@ return 0; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) @@ -1916,6 +1917,7 @@ //return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH); return 0; } +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) @@ -2203,10 +2205,10 @@ .set_tx_power = cfg80211_rtw_set_txpower, .get_tx_power = cfg80211_rtw_get_txpower, .set_power_mgmt = cfg80211_rtw_set_power_mgmt, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) .set_pmksa = cfg80211_rtw_set_pmksa, .del_pmksa = cfg80211_rtw_del_pmksa, .flush_pmksa = cfg80211_rtw_flush_pmksa, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) .mgmt_tx = cfg80211_rtw_mgmt_tx, .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35)) @@ -2290,9 +2292,8 @@ wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT; wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX; - wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS; - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS; wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION; #endif
Hardware configuration
Make sure your hardware is configured in USB host mode.
Board's driver configuration
In order to get you board ready to run the driver for the wifi adapter you must enable various kernel features and applications. You can check that you have all the packages enabled correctly by running:
egrep 'CONFIG_NET[= ]|CONFIG_WIRELESS[= ]|CONFIG_MAC80211[= ]|CONFIG_EMBEDDED|CONFIG_WLAN[= ]|CONFIG_WLAN_80211|CONFIG_CFG80211[= ]|CONFIG_MAC80211_RC_MINSTREL|CONFIG_RTL8712U|CONFIG_FS_APPS_OPENSSL|CONFIG_FS_APPS_WPASUPPLICANT|CONFIG_FS_APPS_WIRELESS_TOOLS|CONFIG_RTL8182U' $DEVDIR/bsp/mach/bspconfig
with expected output:
CONFIG_FS_APPS_OPENSSL=y CONFIG_FS_APPS_WIRELESS_TOOLS=y CONFIG_FS_APPS_WPASUPPLICANT=y CONFIG_EMBEDDED=y CONFIG_NET=y CONFIG_WIRELESS=y CONFIG_CFG80211=y CONFIG_MAC80211=y CONFIG_MAC80211_RC_MINSTREL=y CONFIG_WLAN=y CONFIG_WLAN_80211=y CONFIG_RTL8712U=m
Debug FS configuration
You can add some debugging information files via debugfs:
egrep 'CFG80211_DEBUGFS|MAC80211_DEBUGFS' $DEVDIR/bsp/mach/bspconfig
with expected output:
CONFIG_CFG80211_DEBUGFS=y CONFIG_MAC80211_DEBUGFS=y
Hardware bring
I started by booting the board without the DWA-131 installed and without the driver loaded.
Install DWA-131 WiFi USB dongle
Install dongle, run
lsusb
Expected output:
Bus 001 Device 001: ID 1d6b:0002 Bus 001 Device 003: ID 07d1:3303
The 07d1:3303 is the DWA-131 dongle.
Software bring up
Install 8712u kernel module
Run:
modprobe 8712u
Expected output:
==DriverVersion: v2.6.6.0.20120405== register rtl8712_netdev_ops to netdev_ops rtw_wdev_alloc 8712_usb_endpoint_descriptor(0): bLength=7 bDescriptorType=5 bEndpointAddress=83 wMaxPacketSize=200 bInterval=0 8712_usb_endpoint_descriptor(1): bLength=7 bDescriptorType=5 bEndpointAddress=4 wMaxPacketSize=200 bInterval=0 8712_usb_endpoint_descriptor(2): bLength=7 bDescriptorType=5 bEndpointAddress=6 wMaxPacketSize=200 bInterval=0 8712_usb_endpoint_descriptor(3): bLength=7 bDescriptorType=5 bEndpointAddress=d wMaxPacketSize=200 bInterval=0 8712u : USB_SPEED_HIGH nr_endpoint=4 Boot from EFUSE Autoload OK!! CustomerID = 0x 0 MAC Address from efuse= 14-d6-4d-10-9d-79 cfg80211_rtw_set_power_mgmt usbcore: registered new interface driver r871x_usb_drv
Verify wlan0 exists
Make sure Linux network interface and wireless LAN interface are both found
ifconfig wlan0 iwconfig wlan0
You should get output like:
wlan0 Link encap:Ethernet HWaddr 14:D6:4D:10:9D:79 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
and
wlan0 unassociated Nickname:"rtl_wifi" Mode:Auto Access Point: Not-Associated Sensitivity:0/0 Retry:off RTS thr:off Fragment thr:off Encryption key:off Power Management:off Link Quality:0 Signal level:0 Noise level:0 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0
Power on WiFi sub-system
ifconfig wlan0 up
No output will be generated if successful, unless you have debug enabled.
Ad hoc mode
Ad hoc WiFi networking allows the target device to wait for a host device to connect directly to the target, without the use of a Wireless Access Point (WAP).
Target configuration
Configure DHCP server
When a host connects to the target, it will likely need an IP address. You can run a DHCP server on the target to so the ad hoc network has a DHCP server. You can add something similar to the following to the /etc/dhcpd.conf file.
subnet 10.100.0.0 netmask 255.255.255.0 { range 10.100.0.10 10.100.0.100; option domain-name "example.org"; option domain-name-servers dns1.example.org; option routers 10.100.0.1; option broadcast-address 10.100.0.1; default-lease-time 600; max-lease-time 7200; }
Configure wifi for ad hoc
iwconfig wlan0 mode ad-hoc iwconfig wlan0 channel 4 iwconfig wlan0 essid 'dm368' ifconfig wlan0 10.100.0.1 netmask 255.255.255.0 route add default wlan0
Start DHCP server
touch /var/db/dhcpd.leases dhcpd &
Host configuration
On the host, scan for wireless devices and access points. Select the ESSID name used by the target (dm36 in the example above).
Infrastructure mode
Infrastructure mode requires the use of a Wireless Access Point (WAP) where devices connected to the WAP.
Scan for access points
iwlist wlan0 scan
which lists access points that are in range, like:
wlan0 Scan completed : Cell 01 - Address: 00:26:5A:A4:EC:44 ESSID:"RGA" Protocol:IEEE 802.11bgn Mode:Master Frequency:2.412 GHz (Channel 1) Encryption key:on Bit Rates:150 Mb/s Extra:wpa_ie=dd1a0050f20101000050f20202000050f2040050f20201000050f202 IE: WPA Version 1 Group Cipher : TKIP Pairwise Ciphers (2) : CCMP TKIP Authentication Suites (1) : PSK Extra:rsn_ie=30180100000fac020200000fac04000fac020100000fac020000 IE: IEEE 802.11i/WPA2 Version 1 Group Cipher : TKIP Pairwise Ciphers (2) : CCMP TKIP Authentication Suites (1) : PSK Signal level=32/100 Cell 02 - Address: B8:C7:5D:03:68:3F ESSID:"Futuris" Protocol:IEEE 802.11bgn Mode:Master Frequency:2.412 GHz (Channel 1) Encryption key:on Bit Rates:144 Mb/s Extra:wpa_ie=dd160050f20101000050f20201000050f20201000050f202 IE: WPA Version 1 Group Cipher : TKIP Pairwise Ciphers (1) : TKIP Authentication Suites (1) : PSK Extra:rsn_ie=30180100000fac020200000fac04000fac020100000fac020000 IE: IEEE 802.11i/WPA2 Version 1 Group Cipher : TKIP Pairwise Ciphers (2) : CCMP TKIP Authentication Suites (1) : PSK Signal level=10/100
Attaching WiFi to access point
Security disabled
iwconfig wlan0 essid "Hawley"
WEP security
iwconfig wlan0 essid "Hawley" iwconfig wlan0 key 0001020304
WPA security
mkdir -p /etc/wpa_supplicant cat <<EOF >/etc/wpa_supplicant/wpa_supplicant.conf # Example wpa_supplicant network={ ssid="Baily" psk="very secret passphrase" priority=5 } EOF wpa_supplicant -d -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant.conf -Dwext &
With debug output enabled, you will have lots of information on what is not working if you run into a problem.
Verifying access point association
You can check you are associated with an access point using
iwconfig wlan0