Realtek RTL8188CUS USB WiFi Integration

From RidgeRun Developer Wiki


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