Rt3070usb

== Intro ==
This page explains how to get the rt3070usb (aka rt3070sta) linux driver working in openembedded for the overo on Lisa.
== Background ==
I have an edimax EW-7711UAn usb wifi stick I needed to get working with Lisa. Its USB id is 7392:7711. 
Manufacturer and available at Amazon
My initial search seemed to show the rt2870usb driver was the one to use, and I guess at one time that might have been the case for the chip in this stick. But rt3070usb is now the one to use.
There's a recipe for the rt3070 driver in openembedded (which I'm pulling from : ). The recipe pulls the source code from the ralink website (or get it from this page), patches it, and builds. It's pretty impressive that this driver cross compiles and just works. Well, for me it doesn't compile for me for two reasons : 
* 1. My linux kernel has real-time patches so the init_MUTEX() in the driver source can't be found
* 2. Some sort of device structure change has occurred in the kernel since who knows when
The fixes are:
* 1. replace init_MUTEX(blah) with sema_init(blah,1)
* 2. Apply patch from http://lists.rpmfusion.org/pipermail/rpmfusion-commits/2009-August/005943.html (copied below just in case)
== Building ==
The recipe will be fixed (patch files available here), but until then, here are instructions for building :
In the overo-oe directory type:
: bitbake rt3070
this should bomb while compiling with the following error :
: common/rtmp_init.c:3709: error: implicit declaration of function ‘init_MUTEX’
Then, go to the following directory : overo-oe/tmp/work/overo-angstrom-linux-gnueabi/rt3070-2.1.1.0-r80/2009_0525_RT3070_Linux_STA_v2.1.1.0
Patch common/rtmp_init.c with the one line change : replace init_MUTEX as indicated above
Then, apply patch (at the bottom of this page or here) as follows :
: paul@paul-laptop:~/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/rt3070-2.1.1.0-r80$ patch -p0 < rt3070.patch 
Now, if all is well, doing another "bitbake rt3070" should succeed but before doing that, a quick way to make sure is to attempt the recompilation right from this tmp/work area as follows : 
cd to ~/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/rt3070-2.1.1.0-r80/temp$ 
: then execute the run.do_compile.xxxxx script
:: ./run.do_compile.17833
The resulting module is not small : 
 paul@paul-laptop:~/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/rt3070-2.1.1.0-r80/2009_0525_RT3070_Linux_STA_v2.1.1.0$ ls -l os/linux/rt3070sta.ko 
 -rw-rw-r-- 1 paul paul 9059652 2010-07-29 18:44 os/linux/rt3070sta.ko
I haven't looked into it, but I'm guessing the firmware is now included in the module file and perhaps there's firmware for a bunch of different controllers/cards. The file system space isn't too precious, but this doesn't have an impact on load time (and therefore boot time), so it would be good to resolve this and get it down to a reasonable size.
Update : after rebuilding and deploying my new SD card image I no longer seem to have a big module (now around 600kB). The first time I rebuilt i had a do_setscene warning about get_kernelmajorversion not working followed by do_strip error (probably due to first). retrying without using the bitbake -b method worked, though. Paulcox 16:40, 30 July 2010 (CEST)
To test we can copy the .ko file directly to our overo root filesystem as well as create the /etc/Wireless/blah to put the .dat file or we can simply add the rt3070 recipe to our image recipe, rebuild our omap3-lisa-image. omap3-lisa-image, and create a new sd card.
overo-oe$ vi org.openembedded.dev/recipes/images/omap3-lisa-image.bb 
# omap3 image for Lisa board
require omap3-console-image.bb
ANGSTROM_EXTRA_INSTALL ?= ""
LISA_LIBS = " \
 libevent \
 "
LISA_EXTRAS = " \
 rt3070 \
 screen \
 "
IMAGE_INSTALL += " \
 ${LISA_LIBS} \
 ${LISA_EXTRAS} \
 "
== Configuration ==
Supposedly the driver will look for a configuration file : /etc/Wireless/RT2870STA/RT2870STA.dat but I configured manually instead as follows
: insmod rt3070sta.ko
:: at this point iwconfig shows an ra0 interface
: ifconfig ra0 up
: iwconfig ra0 essid ap_h16
=== wpa_supplicant ===
As usual, the wpa key goes in /etc/wpa_supplicant.conf and started wpa_supplicant with 
: wpa_supplicant -ira0 -c/etc/wpa_supplicant.conf & 
=== DHCP ===
: dhclient ra0
=== Console output === 
root@overo:/home/paul# iwconfig ra0
ra0 RT2870 Wireless ESSID:"ap_h16" Nickname:"RT2870STA"
 Mode:Managed Frequency=2.412 GHz Access Point: 00:25:4B:06:E3:9F 
 Bit Rate=65 Mb/s 
 RTS thr:off Fragment thr:off
 Encryption key:447F-01CB-C235-6BF1-0F8C-0E61-5C88-EEEA
 Link Quality=100/100 Signal level:-39 dBm Noise level:-83 dBm
 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
 Tx excessive retries:0 Invalid misc:0 Missed beacon:0
root@overo:/home/paul# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 7392:7711 
root@overo:/home/paul# ping bill
PING bill.recherche.enac.fr (10.31.4.5) 56(84) bytes of data.
64 bytes from bill.recherche.enac.fr (10.31.4.5): icmp_seq=1 ttl=64 time=367 ms
^C
--- bill.recherche.enac.fr ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 367.279/367.279/367.279/0.000 ms
root@overo:/home/paul# WPA: Group rekeying completed with 00:25:4b:06:e3:9f [GTK=TKIP]
== Patch ==
diff -rupN 2009_0525_RT3070_Linux_STA_v2.1.1.0.old/include/rtmp_os.h 2009_0525_RT3070_Linux_STA_v2.1.1.0/include/rtmp_os.h
--- 2009_0525_RT3070_Linux_STA_v2.1.1.0.old/include/rtmp_os.h	2009-05-20 23:33:56.000000000 -0400
+++ 2009_0525_RT3070_Linux_STA_v2.1.1.0/include/rtmp_os.h	2009-08-04 00:00:46.000000000 -0400
@@ -53,6 +53,7 @@
 */
 typedef struct _RTMP_OS_NETDEV_OP_HOOK_
 {
+ /*
 	void			*open;
 	void			*stop;
 	void			*xmit;
@@ -63,6 +64,8 @@ typedef struct _RTMP_OS_NETDEV_OP_HOOK_
 	unsigned char devAddr[6];
 	unsigned char	devName[16];
 	unsigned char	needProtcted;
+ */
+ struct net_device_ops *netdev_ops;
 }RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK;
 
 
diff -rupN 2009_0525_RT3070_Linux_STA_v2.1.1.0.old/os/linux/rt_linux.c 2009_0525_RT3070_Linux_STA_v2.1.1.0/os/linux/rt_linux.c
--- 2009_0525_RT3070_Linux_STA_v2.1.1.0.old/os/linux/rt_linux.c	2009-05-20 23:33:56.000000000 -0400
+++ 2009_0525_RT3070_Linux_STA_v2.1.1.0/os/linux/rt_linux.c	2009-08-04 00:04:15.000000000 -0400
@@ -1506,20 +1506,21 @@ int RtmpOSNetDevAttach(
 	if (pDevOpHook)
 	{
 		PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(pNetDev);
-	
+		pNetDev->netdev_ops = pDevOpHook->netdev_ops;
+		/*	
 		pNetDev->open			= pDevOpHook->open;
 		pNetDev->stop			= pDevOpHook->stop;
 		pNetDev->hard_start_xmit	= (HARD_START_XMIT_FUNC)(pDevOpHook->xmit);
 		pNetDev->do_ioctl		= pDevOpHook->ioctl;
-		
+		*/
 		/* if you don't implement get_stats, just leave the callback function as NULL, a dummy 
 		 function will make kernel panic.
 		*/
-		if (pDevOpHook->get_stats)
+		/*if (pDevOpHook->get_stats)
 			pNetDev->get_stats = pDevOpHook->get_stats;
-
+		*/
 		/* OS specific flags, here we used to indicate if we are virtual interface */
-		pNetDev->priv_flags = pDevOpHook->priv_flags; 
+		//		pNetDev->priv_flags = pDevOpHook->priv_flags; 
 
 #if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12)
 		pNetDev->get_wireless_stats = rt28xx_get_wireless_stats;
@@ -1544,15 +1545,15 @@ int RtmpOSNetDevAttach(
 #endif // CONFIG_APSTA_MIXED_SUPPORT //
 
 		// copy the net device mac address to the net_device structure.
-		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
+		//		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
 
-		rtnl_locked = pDevOpHook->needProtcted;
+		//		rtnl_locked = pDevOpHook->needProtcted;
 	}
-
+	/*
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
 	pNetDev->validate_addr = NULL;
 #endif
-
+	*/
 	if (rtnl_locked)
 		ret = register_netdevice(pNetDev);
 	else
diff -rupN 2009_0525_RT3070_Linux_STA_v2.1.1.0.old/os/linux/rt_main_dev.c 2009_0525_RT3070_Linux_STA_v2.1.1.0/os/linux/rt_main_dev.c
--- 2009_0525_RT3070_Linux_STA_v2.1.1.0.old/os/linux/rt_main_dev.c	2009-05-20 23:33:56.000000000 -0400
+++ 2009_0525_RT3070_Linux_STA_v2.1.1.0/os/linux/rt_main_dev.c	2009-08-04 00:06:08.000000000 -0400
@@ -504,6 +504,21 @@ err:
 	return (-1);
 } /* End of rt28xx_open */
 
+static const struct net_device_ops rt2870_netdev_ops = {
+ .ndo_open = MainVirtualIF_open,//
+ .ndo_stop = MainVirtualIF_close,//
+ .ndo_do_ioctl = rt28xx_ioctl,//
+ .ndo_get_stats = RT28xx_get_ether_stats,//
+ .ndo_validate_addr = NULL,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef IKANOS_VX_1X0
+ .ndo_start_xmit = IKANOS_DataFramesTx,//
+#else
+ .ndo_start_xmit = rt28xx_send_packets,//
+#endif
+};
+
 
 PNET_DEV RtmpPhyNetDevInit(
 	IN RTMP_ADAPTER *pAd,
@@ -520,6 +535,8 @@ PNET_DEV RtmpPhyNetDevInit(
 	}
 
 	NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
+	pNetDevHook->netdev_ops = &rt2870_netdev_ops;
+	/*
 	pNetDevHook->open = MainVirtualIF_open;
 	pNetDevHook->stop = MainVirtualIF_close;
 	pNetDevHook->xmit = rt28xx_send_packets;
@@ -531,7 +548,7 @@ PNET_DEV RtmpPhyNetDevInit(
 	pNetDevHook->get_stats = RT28xx_get_ether_stats;
 
 	pNetDevHook->needProtcted = FALSE;
-
+	*/
 	RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd);
 	//net_dev->priv = (PVOID)pAd;
 	pAd->net_dev = net_dev;
Category:Software Category:User_Documentation