Author: thompsa
Date: Thu Mar 11 22:05:12 2010
New Revision: 205042
URL: http://svn.freebsd.org/changeset/base/205042

Log:
  - Integrate latest driver code from OpenBSD
  - Drain our tasks from the ieee80211 taskqueue
  - Add more IDs
  
  Submitted by: Akinori Furukoshi

Modified:
  head/sys/dev/usb/usbdevs
  head/sys/dev/usb/wlan/if_run.c
  head/sys/dev/usb/wlan/if_runreg.h
  head/sys/dev/usb/wlan/if_runvar.h

Modified: head/sys/dev/usb/usbdevs
==============================================================================
--- head/sys/dev/usb/usbdevs    Thu Mar 11 22:01:48 2010        (r205041)
+++ head/sys/dev/usb/usbdevs    Thu Mar 11 22:05:12 2010        (r205042)
@@ -270,6 +270,7 @@ vendor LACIE                0x059f  LaCie
 vendor FUJIFILM                0x05a2  Fuji Film
 vendor ARC             0x05a3  ARC
 vendor ORTEK           0x05a4  Ortek
+vendor CISCOLINKSYS3   0x05a6  Cisco-Linksys
 vendor BOSE            0x05a7  Bose
 vendor OMNIVISION      0x05a9  OmniVision
 vendor INSYSTEM                0x05ab  In-System Design
@@ -539,6 +540,7 @@ vendor RIM          0x0fca  Research In Motion
 vendor DYNASTREAM      0x0fcf  Dynastream Innovations
 vendor QUALCOMM                0x1004  Qualcomm
 vendor APACER          0x1005  Apacer
+vendor MOTOROLA4       0x100d  Motorola
 vendor DESKNOTE                0x1019  Desknote
 vendor GIGABYTE                0x1044  GIGABYTE
 vendor WESTERN         0x1058  Western Digital
@@ -635,6 +637,7 @@ vendor LINKSYS3             0x1915  Linksys
 vendor QUALCOMMINC     0x19d2  Qualcomm, Incorporated
 vendor WCH2            0x1a86  QinHeng Electronics
 vendor STELERA         0x1a8d  Stelera Wireless
+vendor OVISLINK                0x1b75  OvisLink
 vendor TCTMOBILE       0x1bbb  TCT Mobile
 vendor TELIT           0x1bc7  Telit
 vendor MPMAN           0x1cae  MpMan
@@ -676,6 +679,7 @@ vendor 3COM2                0x6891  3Com
 vendor EDIMAX          0x7392  Edimax
 vendor INTEL           0x8086  Intel
 vendor INTEL2          0x8087  Intel
+vendor ALLWIN          0x8516  ALLWIN Tech
 vendor SITECOM2                0x9016  Sitecom
 vendor MOSCHIP         0x9710  MosChip Semiconductor
 vendor MARVELL         0x9e88  Marvell Technology Group Ltd.
@@ -755,6 +759,7 @@ product     ACCTON RT3070_1         0xa701  RT3070
 product        ACCTON RT3070_2         0xa702  RT3070
 product ACCTON RT2870_1                0xb522  RT2870
 product        ACCTON RT3070_3         0xc522  RT3070
+product        ACCTON RT3070_5         0xd522  RT3070
 product ACCTON ZD1211B         0xe501  ZD1211B
 
 /* Aceeca products */
@@ -887,6 +892,15 @@ product ALTEC ASC495               0xff05  ASC495 Spea
 /* Allied Telesyn International products */
 product ALLIEDTELESYN ATUSB100 0xb100  AT-USB100
 
+/* ALLWIN Tech products */
+product ALLWIN RT2070          0x2070  RT2070
+product ALLWIN RT2770          0x2770  RT2770
+product ALLWIN RT2870          0x2870  RT2870
+product ALLWIN RT3070          0x3070  RT3070
+product ALLWIN RT3071          0x3071  RT3071
+product ALLWIN RT3072          0x3072  RT3072
+product ALLWIN RT3572          0x3572  RT3572
+
 /* AlphaSmart, Inc. products */
 product ALPHASMART DANA_KB     0xdbac  AlphaSmart Dana Keyboard
 product ALPHASMART DANA_SYNC   0xdf00  AlphaSmart Dana HotSync
@@ -989,7 +1003,8 @@ product ASUS RT2870_2              0x1732  RT2870
 product ASUS RT2870_3          0x1742  RT2870
 product ASUS RT2870_4          0x1760  RT2870
 product ASUS RT2870_5          0x1761  RT2870
-product        ASUS RT3070             0x1784  RT3070
+product        ASUS USBN13             0x1784  USB-N13
+product        ASUS RT3070_1           0x1790  RT3070
 product ASUS P535              0x420f  ASUS P535 PDA
 product        ASUS GMSC               0x422f  ASUS Generic Mass Storage
 product ASUS RT2570            0x1706  RT2500USB Wireless Adapter
@@ -1147,7 +1162,8 @@ product CISCOLINKSYS HU200TS      0x001a  HU20
 product CISCOLINKSYS WUSB54GC  0x0020  WUSB54GC
 product CISCOLINKSYS WUSB54GR  0x0023  WUSB54GR
 product CISCOLINKSYS WUSBF54G  0x0024  WUSBF54G
-product        CISCOLINKSYS2   RT3070  0x4001  RT3070
+product        CISCOLINKSYS2 RT3070    0x4001  RT3070
+product        CISCOLINKSYS3 RT3070    0x0101  RT3070
 
 /* CMOTECH products */
 product CMOTECH CNU510         0x5141  CDMA Technologies USB modem
@@ -1174,6 +1190,8 @@ product CONCEPTRONIC AR5523_2     0x7811  AR5
 product CONCEPTRONIC AR5523_2_NF       0x7812  AR5523 (no firmware)
 product CONCEPTRONIC2 C54RU    0x3c02  C54RU WLAN
 product CONCEPTRONIC2 C54RU2   0x3c22  C54RU
+product CONCEPTRONIC2 RT3070_1 0x3c08  RT3070
+product CONCEPTRONIC2 RT3070_2 0x3c11  RT3070
 product CONCEPTRONIC2 VIGORN61 0x3c25  VIGORN61
 product CONCEPTRONIC2 RT2870_1 0x3c06  RT2870
 product CONCEPTRONIC2 RT2870_2 0x3c07  RT2870
@@ -1326,12 +1344,14 @@ product DLINK2 DWA111           0x3c06  DWA-111
 product DLINK2 RT2870_1                0x3c09  RT2870
 product DLINK2 DWA110          0x3c07  DWA-110
 product DLINK2 RT3072          0x3c0a  RT3072
+product DLINK2 RT3072_1                0x3c0b  RT3072
 product DLINK2 RT3070_1                0x3c0d  RT3070
 product DLINK2 RT3070_2                0x3c0e  RT3070
 product DLINK2 RT3070_3                0x3c0f  RT3070
 product DLINK2 RT2870_2                0x3c11  RT2870
 product DLINK2 DWA130          0x3c13  DWA-130
 product DLINK2 RT3070_4                0x3c15  RT3070
+product DLINK2 RT3070_5                0x3c16  RT3070
 product DLINK3 DWM652          0x3e04  DWM-652
 
 /* DMI products */
@@ -1902,6 +1922,7 @@ product LINKSYS4 WUSB100  0x0070  WUSB100
 product LINKSYS4 WUSB600N      0x0071  WUSB600N
 product LINKSYS4 WUSB54GCV2    0x0073  WUSB54GC v2
 product LINKSYS4 WUSB54GCV3    0x0077  WUSB54GC v3
+product LINKSYS4 RT3070                0x0078  RT3070
 product LINKSYS4 WUSB600NV2    0x0079  WUSB600N v2
 
 /* Logitech products */
@@ -1975,6 +1996,8 @@ product MELCO KG54L               0x00da  WLI-U2-KG54L
 product MELCO WLIUCG300N       0x00e8  WLI-UC-G300N
 product MELCO SG54HG           0x00f4  WLI-U2-SG54HG
 product MELCO WLIUCAG300N      0x012e  WLI-UC-AG300N
+product MELCO RT2870_1         0x0148  RT2870
+product MELCO RT2870_2         0x0150  RT2870
 product MELCO WLIUCGN          0x015d  WLI-UC-GN
 
 /* Merlin products */
@@ -1995,7 +2018,9 @@ product MGE UPS2          0xffff  MGE UPS SYSTEMS
 product MSI BT_DONGLE          0x1967  Bluetooth USB dongle
 product MSI RT3070_1           0x3820  RT3070
 product MSI RT3070_2           0x3821  RT3070
+product MSI RT3070_8           0x3822  RT3070
 product MSI RT3070_3           0x3870  RT3070
+product MSI RT3070_9           0x3871  RT3070
 product MSI UB11B              0x6823  UB11B
 product MSI RT2570             0x6861  RT2570
 product MSI RT2570_2           0x6865  RT2570
@@ -2004,7 +2029,9 @@ product MSI RT2573_1              0x6874  RT2573
 product MSI RT2573_2           0x6877  RT2573
 product MSI RT3070_4           0x6899  RT3070
 product MSI RT3070_5           0x821a  RT3070
+product MSI RT3070_10          0x822a  RT3070
 product MSI RT3070_6           0x870a  RT3070
+product MSI RT3070_11          0x871a  RT3070
 product MSI RT3070_7           0x899a  RT3070
 product MSI RT2573_3           0xa861  RT2573
 product MSI RT2573_4           0xa874  RT2573
@@ -2085,6 +2112,8 @@ product MOTOROLA2 A41XV32X        0x2a22  A41x/V
 product MOTOROLA2 E398         0x4810  E398 Mobile Phone
 product MOTOROLA2 USBLAN       0x600c  USBLAN
 product MOTOROLA2 USBLAN2      0x6027  USBLAN
+product MOTOROLA4 RT2770       0x9031  RT2770
+product MOTOROLA4 RT3070       0x9032  RT3070
 
 /* MultiTech products */
 product MULTITECH ATLAS                0xf101  MT5634ZBA-USB modem
@@ -2255,6 +2284,9 @@ product OPTION MODHSXPA           0xd013  Globetro
 product OPTION ICON321         0xd031  Globetrotter HSUPA
 product OPTION ICON505         0xd055  Globetrotter iCON 505
 
+/* OvisLink product */
+product OVISLINK RT3072                0x3072  RT3072
+
 /* OQO */
 product OQO WIFI01             0x0002  model 01 WiFi interface
 product OQO BT01               0x0003  model 01 Bluetooth interface
@@ -2289,6 +2321,7 @@ product PARA RT3070               0x8888  RT3070
 product PEGATRON RT2870                0x0002  RT2870
 product PEGATRON RT3070                0x000c  RT3070
 product PEGATRON RT3070_2      0x000e  RT3070
+product PEGATRON RT3070_3      0x0010  RT3070
 
 /* Peracom products */
 product PERACOM SERIAL1                0x0001  Serial
@@ -2508,7 +2541,9 @@ product RALINK RT2870             0x2870  RT2870
 product RALINK RT3070          0x3070  RT3070
 product RALINK RT3071          0x3071  RT3071
 product RALINK RT3072          0x3072  RT3072
+product RALINK RT3370          0x3370  RT3370
 product RALINK RT3572          0x3572  RT3572
+product RALINK RT8070          0x8070  RT8070
 product RALINK RT2570_3                0x9020  RT2500USB Wireless Adapter
 product RALINK RT2573_2                0x9021  RT2501USB Wireless Adapter
 
@@ -2745,6 +2780,7 @@ product SITECOMEU RT3070_3        0x003c  RT3070
 product SITECOMEU RT3070_4     0x003d  RT3070
 product SITECOMEU RT3070       0x003e  RT3070
 product SITECOMEU WL608                0x003f  WL-608
+product SITECOMEU RT3071       0x0040  RT3071
 product SITECOMEU RT3072_1     0x0041  RT3072
 product SITECOMEU RT3072_2     0x0042  RT3072
 product SITECOMEU RT3072_3     0x0047  RT3072
@@ -2881,6 +2917,7 @@ product SURECOM RT2573            0x31f3  RT2573
 
 /* Sweex products */
 product SWEEX ZD1211           0x1809  ZD1211
+product SWEEX2 LW153           0x0153  LW153
 product SWEEX2 LW303           0x0302  LW303
 product SWEEX2 LW313           0x0313  LW313
 
@@ -2936,6 +2973,7 @@ product TOPRE HHKB                0x0100  HHKB Professi
 
 /* Toshiba Corporation products */
 product TOSHIBA POCKETPC_E740  0x0706  PocketPC e740
+product TOSHIBA RT3070         0x0a07  RT3070
 product TOSHIBA G450           0x0d45  G450 modem
 product TOSHIBA HSDPA          0x1302  G450 modem
 
@@ -3116,3 +3154,4 @@ product ZYXEL M202                0x340a  M-202
 product ZYXEL G220V2           0x340f  G-220 v2
 product ZYXEL G202             0x3410  G-202
 product ZYXEL RT2870_1         0x3416  RT2870
+product ZYXEL RT2870_2         0x341a  RT2870

Modified: head/sys/dev/usb/wlan/if_run.c
==============================================================================
--- head/sys/dev/usb/wlan/if_run.c      Thu Mar 11 22:01:48 2010        
(r205041)
+++ head/sys/dev/usb/wlan/if_run.c      Thu Mar 11 22:05:12 2010        
(r205042)
@@ -1,8 +1,9 @@
 /*     $FreeBSD$       */
 
 /*-
- * Copyright (c) 2008,2009 Damien Bergamini <damien.bergam...@free.fr>
- *     ported to FreeBSD by Akinori Furukoshi <moonlightak...@yahoo.ca>
+ * Copyright (c) 2008,2010 Damien Bergamini <damien.bergam...@free.fr>
+ * ported to FreeBSD by Akinori Furukoshi <moonlightak...@yahoo.ca>
+ * USB Consulting, Hans Petter Selasky <hsela...@freebsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,8 +18,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* release date Jan. 09, 2010 */
-
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -107,11 +106,20 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT2870_3) },
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT2870_4) },
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT2870_5) },
+    { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT3070) },
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT3070_1) },
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT3070_2) },
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT3070_3) },
     { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT3070_4) },
+    { USB_VP(USB_VENDOR_ACCTON,                USB_PRODUCT_ACCTON_RT3070_5) },
     { USB_VP(USB_VENDOR_AIRTIES,       USB_PRODUCT_AIRTIES_RT3070) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT2070) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT2770) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT2870) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT3070) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT3071) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT3072) },
+    { USB_VP(USB_VENDOR_ALLWIN,                USB_PRODUCT_ALLWIN_RT3572) },
     { USB_VP(USB_VENDOR_AMIGO,         USB_PRODUCT_AMIGO_RT2870_1) },
     { USB_VP(USB_VENDOR_AMIGO,         USB_PRODUCT_AMIGO_RT2870_2) },
     { USB_VP(USB_VENDOR_AMIT,          USB_PRODUCT_AMIT_CGWLUSB2GNR) },
@@ -122,6 +130,8 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_ASUS,          USB_PRODUCT_ASUS_RT2870_3) },
     { USB_VP(USB_VENDOR_ASUS,          USB_PRODUCT_ASUS_RT2870_4) },
     { USB_VP(USB_VENDOR_ASUS,          USB_PRODUCT_ASUS_RT2870_5) },
+    { USB_VP(USB_VENDOR_ASUS,          USB_PRODUCT_ASUS_USBN13) },
+    { USB_VP(USB_VENDOR_ASUS,          USB_PRODUCT_ASUS_RT3070_1) },
     { USB_VP(USB_VENDOR_ASUS2,         USB_PRODUCT_ASUS2_USBN11) },
     { USB_VP(USB_VENDOR_AZUREWAVE,     USB_PRODUCT_AZUREWAVE_RT2870_1) },
     { USB_VP(USB_VENDOR_AZUREWAVE,     USB_PRODUCT_AZUREWAVE_RT2870_2) },
@@ -133,6 +143,8 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_BELKIN,                USB_PRODUCT_BELKIN_F6D4050V1) },
     { USB_VP(USB_VENDOR_BELKIN,                USB_PRODUCT_BELKIN_RT2870_1) },
     { USB_VP(USB_VENDOR_BELKIN,                USB_PRODUCT_BELKIN_RT2870_2) },
+    { USB_VP(USB_VENDOR_CISCOLINKSYS2, USB_PRODUCT_CISCOLINKSYS2_RT3070) },
+    { USB_VP(USB_VENDOR_CISCOLINKSYS3, USB_PRODUCT_CISCOLINKSYS2_RT3070) },
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_1) },
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_2) },
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_3) },
@@ -141,6 +153,8 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_6) },
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_7) },
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_8) },
+    { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_1) },
+    { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_2) },
     { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_VIGORN61) },
     { USB_VP(USB_VENDOR_COREGA,                
USB_PRODUCT_COREGA_CGWLUSB300GNM) },
     { USB_VP(USB_VENDOR_COREGA,                USB_PRODUCT_COREGA_RT2870_1) },
@@ -157,7 +171,9 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_DLINK2,                USB_PRODUCT_DLINK2_RT3070_2) },
     { USB_VP(USB_VENDOR_DLINK2,                USB_PRODUCT_DLINK2_RT3070_3) },
     { USB_VP(USB_VENDOR_DLINK2,                USB_PRODUCT_DLINK2_RT3070_4) },
+    { USB_VP(USB_VENDOR_DLINK2,                USB_PRODUCT_DLINK2_RT3070_5) },
     { USB_VP(USB_VENDOR_DLINK2,                USB_PRODUCT_DLINK2_RT3072) },
+    { USB_VP(USB_VENDOR_DLINK2,                USB_PRODUCT_DLINK2_RT3072_1) },
     { USB_VP(USB_VENDOR_EDIMAX,                USB_PRODUCT_EDIMAX_EW7717) },
     { USB_VP(USB_VENDOR_EDIMAX,                USB_PRODUCT_EDIMAX_EW7718) },
     { USB_VP(USB_VENDOR_EDIMAX,                USB_PRODUCT_EDIMAX_RT2870_1) },
@@ -178,6 +194,7 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_IODATA,                USB_PRODUCT_IODATA_RT3072_2) },
     { USB_VP(USB_VENDOR_IODATA,                USB_PRODUCT_IODATA_RT3072_3) },
     { USB_VP(USB_VENDOR_IODATA,                USB_PRODUCT_IODATA_RT3072_4) },
+    { USB_VP(USB_VENDOR_LINKSYS4,      USB_PRODUCT_LINKSYS4_RT3070) },
     { USB_VP(USB_VENDOR_LINKSYS4,      USB_PRODUCT_LINKSYS4_WUSB100) },
     { USB_VP(USB_VENDOR_LINKSYS4,      USB_PRODUCT_LINKSYS4_WUSB54GCV3) },
     { USB_VP(USB_VENDOR_LINKSYS4,      USB_PRODUCT_LINKSYS4_WUSB600N) },
@@ -185,9 +202,13 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_LOGITEC,       USB_PRODUCT_LOGITEC_RT2870_1) },
     { USB_VP(USB_VENDOR_LOGITEC,       USB_PRODUCT_LOGITEC_RT2870_2) },
     { USB_VP(USB_VENDOR_LOGITEC,       USB_PRODUCT_LOGITEC_RT2870_3) },
+    { USB_VP(USB_VENDOR_MELCO,         USB_PRODUCT_MELCO_RT2870_1) },
+    { USB_VP(USB_VENDOR_MELCO,         USB_PRODUCT_MELCO_RT2870_2) },
     { USB_VP(USB_VENDOR_MELCO,         USB_PRODUCT_MELCO_WLIUCAG300N) },
     { USB_VP(USB_VENDOR_MELCO,         USB_PRODUCT_MELCO_WLIUCG300N) },
     { USB_VP(USB_VENDOR_MELCO,         USB_PRODUCT_MELCO_WLIUCGN) },
+    { USB_VP(USB_VENDOR_MOTOROLA4,     USB_PRODUCT_MOTOROLA4_RT2770) },
+    { USB_VP(USB_VENDOR_MOTOROLA4,     USB_PRODUCT_MOTOROLA4_RT3070) },
     { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_1) },
     { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_2) },
     { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_3) },
@@ -195,10 +216,16 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_5) },
     { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_6) },
     { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_7) },
+    { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_8) },
+    { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_9) },
+    { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_10) },
+    { USB_VP(USB_VENDOR_MSI,           USB_PRODUCT_MSI_RT3070_11) },
+    { USB_VP(USB_VENDOR_OVISLINK,      USB_PRODUCT_OVISLINK_RT3072) },
     { USB_VP(USB_VENDOR_PARA,          USB_PRODUCT_PARA_RT3070) },
     { USB_VP(USB_VENDOR_PEGATRON,      USB_PRODUCT_PEGATRON_RT2870) },
     { USB_VP(USB_VENDOR_PEGATRON,      USB_PRODUCT_PEGATRON_RT3070) },
     { USB_VP(USB_VENDOR_PEGATRON,      USB_PRODUCT_PEGATRON_RT3070_2) },
+    { USB_VP(USB_VENDOR_PEGATRON,      USB_PRODUCT_PEGATRON_RT3070_3) },
     { USB_VP(USB_VENDOR_PHILIPS,       USB_PRODUCT_PHILIPS_RT2870) },
     { USB_VP(USB_VENDOR_PLANEX2,       USB_PRODUCT_PLANEX2_GWUS300MINIS) },
     { USB_VP(USB_VENDOR_PLANEX2,       USB_PRODUCT_PLANEX2_GWUSMICRON) },
@@ -212,7 +239,9 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_RALINK,                USB_PRODUCT_RALINK_RT3070) },
     { USB_VP(USB_VENDOR_RALINK,                USB_PRODUCT_RALINK_RT3071) },
     { USB_VP(USB_VENDOR_RALINK,                USB_PRODUCT_RALINK_RT3072) },
+    { USB_VP(USB_VENDOR_RALINK,                USB_PRODUCT_RALINK_RT3370) },
     { USB_VP(USB_VENDOR_RALINK,                USB_PRODUCT_RALINK_RT3572) },
+    { USB_VP(USB_VENDOR_RALINK,                USB_PRODUCT_RALINK_RT8070) },
     { USB_VP(USB_VENDOR_SAMSUNG2,      USB_PRODUCT_SAMSUNG2_RT2870_1) },
     { USB_VP(USB_VENDOR_SENAO,         USB_PRODUCT_SENAO_RT2870_1) },
     { USB_VP(USB_VENDOR_SENAO,         USB_PRODUCT_SENAO_RT2870_2) },
@@ -234,6 +263,7 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3070_2) },
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3070_3) },
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3070_4) },
+    { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3071) },
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3072_1) },
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3072_2) },
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_RT3072_3) },
@@ -243,8 +273,10 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_SITECOMEU,     USB_PRODUCT_SITECOMEU_WL608) },
     { USB_VP(USB_VENDOR_SPARKLAN,      USB_PRODUCT_SPARKLAN_RT2870_1) },
     { USB_VP(USB_VENDOR_SPARKLAN,      USB_PRODUCT_SPARKLAN_RT3070) },
+    { USB_VP(USB_VENDOR_SWEEX2,                USB_PRODUCT_SWEEX2_LW153) },
     { USB_VP(USB_VENDOR_SWEEX2,                USB_PRODUCT_SWEEX2_LW303) },
     { USB_VP(USB_VENDOR_SWEEX2,                USB_PRODUCT_SWEEX2_LW313) },
+    { USB_VP(USB_VENDOR_TOSHIBA,       USB_PRODUCT_TOSHIBA_RT3070) },
     { USB_VP(USB_VENDOR_UMEDIA,                USB_PRODUCT_UMEDIA_RT2870_1) },
     { USB_VP(USB_VENDOR_ZCOM,          USB_PRODUCT_ZCOM_RT2870_1) },
     { USB_VP(USB_VENDOR_ZCOM,          USB_PRODUCT_ZCOM_RT2870_2) },
@@ -254,6 +286,7 @@ static const struct usb_device_id run_de
     { USB_VP(USB_VENDOR_ZINWELL,       USB_PRODUCT_ZINWELL_RT3072_1) },
     { USB_VP(USB_VENDOR_ZINWELL,       USB_PRODUCT_ZINWELL_RT3072_2) },
     { USB_VP(USB_VENDOR_ZYXEL,         USB_PRODUCT_ZYXEL_RT2870_1) },
+    { USB_VP(USB_VENDOR_ZYXEL,         USB_PRODUCT_ZYXEL_RT2870_2) },
 };
 
 MODULE_DEPEND(run, wlan, 1, 1, 1);
@@ -340,10 +373,12 @@ static int        run_raw_xmit(struct ieee80211
                    const struct ieee80211_bpf_params *);
 static void    run_start(struct ifnet *);
 static int     run_ioctl(struct ifnet *, u_long, caddr_t);
+static void    run_set_agc(struct run_softc *, uint8_t);
 static void    run_select_chan_group(struct run_softc *, int);
 static void    run_set_rx_antenna(struct run_softc *, int);
 static void    run_rt2870_set_chan(struct run_softc *, u_int);
 static void    run_rt3070_set_chan(struct run_softc *, u_int);
+static void    run_rt3572_set_chan(struct run_softc *, u_int);
 static int     run_set_chan(struct run_softc *, struct ieee80211_channel *);
 static void    run_set_channel(struct ieee80211com *);
 static void    run_scan_start(struct ieee80211com *);
@@ -369,6 +404,7 @@ static int  run_bbp_init(struct run_softc
 static int     run_rt3070_rf_init(struct run_softc *);
 static int     run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
                    uint8_t *);
+static void    run_rt3070_rf_setup(struct run_softc *);
 static int     run_txrx_enable(struct run_softc *);
 static void    run_init(void *);
 static void    run_init_locked(struct run_softc *);
@@ -398,8 +434,8 @@ static const struct rfprog {
 
 struct {
        uint8_t n, r, k;
-} run_rf3020_freqs[] = {
-       RT3070_RF3020
+} rt3070_freqs[] = {
+       RT3070_RF3052
 };
 
 static const struct {
@@ -407,6 +443,8 @@ static const struct {
        uint8_t val;
 } rt3070_def_rf[] = {
        RT3070_DEF_RF
+},rt3572_def_rf[] = {
+       RT3572_DEF_RF
 };
 
 static const struct usb_config run_config[RUN_N_XFER] = {
@@ -502,6 +540,7 @@ run_attach(device_t self)
        struct usb_attach_arg *uaa = device_get_ivars(self);
        struct ieee80211com *ic;
        struct ifnet *ifp;
+       uint32_t ver;
        int i, ntries, error;
        uint8_t iface_index, bands;
 
@@ -513,11 +552,10 @@ run_attach(device_t self)
            MTX_NETWORK_LOCK, MTX_DEF);
 
        iface_index = RT2860_IFACE_INDEX;
-       /* Rx transfer has own lock */
        error = usbd_transfer_setup(uaa->device, &iface_index,
            sc->sc_xfer, run_config, RUN_N_XFER, sc, &sc->sc_mtx);
        if (error) {
-               device_printf(self, "could not allocate USB Tx transfers, "
+               device_printf(self, "could not allocate USB transfers, "
                    "err=%s\n", usbd_errstr(error));
                goto detach;
        }
@@ -526,11 +564,11 @@ run_attach(device_t self)
 
        /* wait for the chip to settle */
        for (ntries = 0; ntries < 100; ntries++) {
-               if (run_read(sc, RT2860_ASIC_VER_ID, &sc->mac_rev) != 0){
+               if (run_read(sc, RT2860_ASIC_VER_ID, &ver) != 0){
                        RUN_UNLOCK(sc);
                        goto detach;
                }
-               if (sc->mac_rev != 0 && sc->mac_rev != 0xffffffff)
+               if (ver != 0 && ver != 0xffffffff)
                        break;
                run_delay(sc, 10);
        }
@@ -540,13 +578,15 @@ run_attach(device_t self)
                RUN_UNLOCK(sc);
                goto detach;
        }
+       sc->mac_ver = ver >> 16;
+       sc->mac_rev = ver & 0xffff;
 
        /* retrieve RF rev. no and various other things from EEPROM */
        run_read_eeprom(sc);
 
        device_printf(sc->sc_dev,
            "MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n",
-           sc->mac_rev >> 16, sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev),
+           sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev),
            sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
 
        if ((error = run_load_microcode(sc)) != 0) {
@@ -609,7 +649,9 @@ run_attach(device_t self)
         * Do this by own because h/w supports
         * more channels than ieee80211_init_channels()
         */
-       if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) {
+       if (sc->rf_rev == RT2860_RF_2750 ||
+           sc->rf_rev == RT2860_RF_2850 ||
+           sc->rf_rev == RT3070_RF_3052) {
                /* set supported .11a rates */
                for (i = 14; i < nitems(rt2860_rf2850); i++) {
                        uint8_t chan = rt2860_rf2850[i].chan;
@@ -743,11 +785,15 @@ run_vap_delete(struct ieee80211vap *vap)
 
        sc = ifp->if_softc;
 
-       if (ifp && ifp->if_flags & IFF_UP){
-               RUN_LOCK(sc);
-               run_stop(sc);
-               RUN_UNLOCK(sc);
-       }
+       RUN_LOCK(sc);
+       sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
+       RUN_UNLOCK(sc);
+
+       /* drain them all */
+       usb_callout_drain(&sc->sc_rvp->amrr_ch);
+       ieee80211_draintask(ic, &sc->sc_rvp->amrr_task);
+       ieee80211_draintask(ic, &sc->wme_task);
+       ieee80211_draintask(ic, &sc->usb_timeout_task);
 
        ieee80211_amrr_cleanup(&rvp->amrr);
        ieee80211_vap_detach(vap);
@@ -808,7 +854,9 @@ run_load_microcode(struct run_softc *sc)
        const uint64_t *temp;
        uint64_t bytes;
 
+       RUN_UNLOCK(sc);
        fw = firmware_get("runfw");
+       RUN_LOCK(sc);
        if(fw == NULL){
                device_printf(sc->sc_dev,
                    "failed loadfirmware of file %s\n", "runfw");
@@ -829,14 +877,11 @@ run_load_microcode(struct run_softc *sc)
         * last half is for rt3071.
         */
        base = fw->data;
-       if ((sc->mac_rev >> 16) != 0x2860 &&
-           (sc->mac_rev >> 16) != 0x2872 &&
-           (sc->mac_rev >> 16) != 0x3070 &&
-           (sc->mac_rev >> 16) != 0x3572){
+       if ((sc->mac_ver) != 0x2860 &&
+           (sc->mac_ver) != 0x2872 &&
+           (sc->mac_ver) != 0x3070){ 
                base += 4096;
-               device_printf(sc->sc_dev, "loading RT3071 firmware\n");
-       } else
-               device_printf(sc->sc_dev, "loading RT2870 firmware\n");
+       }
 
        /* cheap sanity check */
        temp = fw->data;
@@ -866,7 +911,7 @@ run_load_microcode(struct run_softc *sc)
        run_delay(sc, 10);
 
        run_write(sc, RT2860_H2M_MAILBOX, 0);
-       if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_BOOT, 0)) != 0)
+       if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0)
                goto fail;
 
        /* wait until microcontroller is ready */
@@ -884,7 +929,8 @@ run_load_microcode(struct run_softc *sc)
                error = ETIMEDOUT;
                goto fail;
        }
-       DPRINTF("microcode successfully loaded after %d tries\n", ntries);
+       device_printf(sc->sc_dev, "firmware %s loaded\n",
+           (base == fw->data) ? "RT2870" : "RT3071");
 
 fail:
        firmware_put(fw, FIRMWARE_UNLOAD);
@@ -1283,7 +1329,7 @@ run_read_eeprom(struct run_softc *sc)
 
        /* check whether the ROM is eFUSE ROM or EEPROM */
        sc->sc_srom_read = run_eeprom_read_2;
-       if ((sc->mac_rev & 0xfff00000) >= 0x30700000) {
+       if (sc->mac_ver >= 0x3070) {
                run_read(sc, RT3070_EFUSE_CTRL, &tmp);
                DPRINTF("EFUSE_CTRL=0x%08x\n", tmp);
                if (tmp & RT3070_SEL_EFUSE)
@@ -1305,21 +1351,32 @@ run_read_eeprom(struct run_softc *sc)
        sc->sc_bssid[4] = val & 0xff;
        sc->sc_bssid[5] = val >> 8;
 
-       /* read default BBP settings */
-       for (i = 0; i < 8; i++) {
+       /* read vender BBP settings */
+       for (i = 0; i < 10; i++) {
                run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val);
                sc->bbp[i].val = val & 0xff;
                sc->bbp[i].reg = val >> 8;
                DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val);
        }
+       if (sc->mac_ver >= 0x3071) {
+               /* read vendor RF settings */
+               for (i = 0; i < 10; i++) {
+                       run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val);
+                       sc->rf[i].val = val & 0xff;
+                       sc->rf[i].reg = val >> 8;
+                       DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg,
+                           sc->rf[i].val);
+               }
+       }
 
        /* read RF frequency offset from EEPROM */
        run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val);
        sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
        DPRINTF("EEPROM freq offset %d\n", sc->freq & 0xff);
 
-       if ((sc->leds = val >> 8) != 0xff) {
+       if (val >> 8 != 0xff) {
                /* read LEDs operating mode */
+               sc->leds = val >> 8;
                run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]);
                run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]);
                run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]);
@@ -1337,7 +1394,12 @@ run_read_eeprom(struct run_softc *sc)
        run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
        if (val == 0xffff) {
                DPRINTF("invalid EEPROM antenna info, using default\n");
-               if ((sc->mac_rev >> 16) >= 0x3070) {
+               if (sc->mac_ver == 0x3572) {
+                       /* default to RF3052 2T2R */
+                       sc->rf_rev = RT3070_RF_3052;
+                       sc->ntxchains = 2;
+                       sc->nrxchains = 2;
+               } else if (sc->mac_ver >= 0x3070) {
                        /* default to RF3020 1T1R */
                        sc->rf_rev = RT3070_RF_3020;
                        sc->ntxchains = 1;
@@ -1356,13 +1418,18 @@ run_read_eeprom(struct run_softc *sc)
        DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n",
            sc->rf_rev, sc->ntxchains, sc->nrxchains);
 
-       /* check if RF supports automatic Tx access gain control */
        run_srom_read(sc, RT2860_EEPROM_CONFIG, &val);
        DPRINTF("EEPROM CFG 0x%04x\n", val);
+       /* check if driver should patch the DAC issue */
+       if ((val >> 8) != 0xff)
+               sc->patch_dac = (val >> 15) & 1;
        if ((val & 0xff) != 0xff) {
                sc->ext_5ghz_lna = (val >> 3) & 1;
                sc->ext_2ghz_lna = (val >> 2) & 1;
+               /* check if RF supports automatic Tx access gain control */
                sc->calib_2ghz = sc->calib_5ghz = (val >> 1) & 1;
+               /* check if we have a hardware radio switch */
+               sc->rfswitch = val & 1;
        }
 
        /* read power settings for 2GHz channels */
@@ -1385,7 +1452,7 @@ run_read_eeprom(struct run_softc *sc)
                    rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]);
        }
        /* read power settings for 5GHz channels */
-       for (i = 0; i < 36; i += 2) {
+       for (i = 0; i < 40; i += 2) {
                run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val);
                sc->txpow1[i + 14] = (int8_t)(val & 0xff);
                sc->txpow1[i + 15] = (int8_t)(val >> 8);
@@ -1395,7 +1462,7 @@ run_read_eeprom(struct run_softc *sc)
                sc->txpow2[i + 15] = (int8_t)(val >> 8);
        }
        /* fix broken Tx power entries */
-       for (i = 0; i < 36; i++) {
+       for (i = 0; i < 40; i++) {
                if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
                        sc->txpow1[14 + i] = 5;
                if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
@@ -1444,14 +1511,32 @@ run_read_eeprom(struct run_softc *sc)
        sc->rssi_2ghz[0] = val & 0xff;  /* Ant A */
        sc->rssi_2ghz[1] = val >> 8;    /* Ant B */
        run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val);
-       sc->rssi_2ghz[2] = val & 0xff;  /* Ant C */
+       if (sc->mac_ver >= 0x3070) {
+               /*
+                * On RT3070 chips (limited to 2 Rx chains), this ROM
+                * field contains the Tx mixer gain for the 2GHz band.
+                */
+               if ((val & 0xff) != 0xff)
+                       sc->txmixgain_2ghz = val & 0x7;
+               DPRINTF("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz);
+       } else
+               sc->rssi_2ghz[2] = val & 0xff;  /* Ant C */
        sc->lna[2] = val >> 8;          /* channel group 2 */
 
        run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val);
        sc->rssi_5ghz[0] = val & 0xff;  /* Ant A */
        sc->rssi_5ghz[1] = val >> 8;    /* Ant B */
        run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val);
-       sc->rssi_5ghz[2] = val & 0xff;  /* Ant C */
+       if (sc->mac_ver == 0x3572) {
+               /*
+                * On RT3572 chips (limited to 2 Rx chains), this ROM
+                * field contains the Tx mixer gain for the 5GHz band.
+                */
+               if ((val & 0xff) != 0xff)
+                       sc->txmixgain_5ghz = val & 0x7;
+               DPRINTF("tx mixer gain=%u (5GHz)\n", sc->txmixgain_5ghz);
+       } else
+               sc->rssi_5ghz[2] = val & 0xff;  /* Ant C */
        sc->lna[3] = val >> 8;          /* channel group 3 */
 
        run_srom_read(sc, RT2860_EEPROM_LNA, &val);
@@ -2639,7 +2724,7 @@ run_tx(struct run_softc *sc, struct mbuf
                        dur = rt2860_rates[ridx].sp_ack_dur;
                else
                        dur = rt2860_rates[ridx].lp_ack_dur;
-               *(uint16_t *)wh->i_dur = htole16(dur + sc->sifs);
+               *(uint16_t *)wh->i_dur = htole16(dur);
        }
 
        /* reserve slots for mgmt packets, just in case */
@@ -3006,9 +3091,26 @@ run_ioctl(struct ifnet *ifp, u_long cmd,
 }
 
 static void
+run_set_agc(struct run_softc *sc, uint8_t agc)
+{
+       uint8_t bbp;
+
+       if (sc->mac_ver == 0x3572) {
+               run_bbp_read(sc, 27, &bbp);
+               bbp &= ~(0x3 << 5);
+               run_bbp_write(sc, 27, bbp | 0 << 5);    /* select Rx0 */
+               run_bbp_write(sc, 66, agc);
+               run_bbp_write(sc, 27, bbp | 1 << 5);    /* select Rx1 */
+               run_bbp_write(sc, 66, agc);
+       } else
+               run_bbp_write(sc, 66, agc);
+}
+
+static void
 run_select_chan_group(struct run_softc *sc, int group)
 {
        uint32_t tmp;
+       uint8_t agc;
 
        run_bbp_write(sc, 62, 0x37 - sc->lna[group]);
        run_bbp_write(sc, 63, 0x37 - sc->lna[group]);
@@ -3024,13 +3126,14 @@ run_select_chan_group(struct run_softc *
                        run_bbp_write(sc, 75, 0x50);
                }
        } else {
-               if (sc->ext_5ghz_lna) {
+               if (sc->mac_ver == 0x3572)
+                       run_bbp_write(sc, 82, 0x94);
+               else
                        run_bbp_write(sc, 82, 0xf2);
+               if (sc->ext_5ghz_lna)
                        run_bbp_write(sc, 75, 0x46);
-               } else {
-                       run_bbp_write(sc, 82, 0xf2);
+               else 
                        run_bbp_write(sc, 75, 0x50);
-               }
        }
 
        run_read(sc, RT2860_TX_BAND_CFG, &tmp);
@@ -3053,13 +3156,26 @@ run_select_chan_group(struct run_softc *
                if (sc->nrxchains > 1)
                        tmp |= RT2860_LNA_PE_A1_EN;
        }
-       run_write(sc, RT2860_TX_PIN_CFG, tmp);
+       if (sc->mac_ver == 0x3572) {
+               run_rt3070_rf_write(sc, 8, 0x00);
+               run_write(sc, RT2860_TX_PIN_CFG, tmp);
+               run_rt3070_rf_write(sc, 8, 0x80);
+       } else
+               run_write(sc, RT2860_TX_PIN_CFG, tmp);
 
        /* set initial AGC value */
-       if (group == 0)
-               run_bbp_write(sc, 66, 0x2e + sc->lna[0]);
-       else
-               run_bbp_write(sc, 66, 0x32 + (sc->lna[group] * 5) / 3);
+       if (group == 0) {       /* 2GHz band */
+               if (sc->mac_ver >= 0x3070)
+                       agc = 0x1c + sc->lna[0] * 2;
+               else
+                       agc = 0x2e + sc->lna[0];
+       } else {                /* 5GHz band */
+               if (sc->mac_ver == 0x3572)
+                       agc = 0x22 + (sc->lna[group] * 5) / 3;
+               else
+                       agc = 0x32 + (sc->lna[group] * 5) / 3;
+       }
+       run_set_agc(sc, agc);
 }
 
 static void
@@ -3122,18 +3238,22 @@ run_rt3070_set_chan(struct run_softc *sc
 {
        int8_t txpow1, txpow2;
        uint8_t rf;
+       int i;
 
        /* RT3070 is 2GHz only */
        KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n"));
 
+       /* find the settings for this channel (we know it exists) */
+       for (i = 0; rt2860_rf2850[i].chan != chan; i++);
+
        /* use Tx power values from EEPROM */
-       txpow1 = sc->txpow1[chan - 1];
-       txpow2 = sc->txpow2[chan - 1];
+       txpow1 = sc->txpow1[i];
+       txpow2 = sc->txpow2[i];
 
-       run_rt3070_rf_write(sc, 2, run_rf3020_freqs[chan - 1].n);
-       run_rt3070_rf_write(sc, 3, run_rf3020_freqs[chan - 1].k);
+       run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
+       run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
        run_rt3070_rf_read(sc, 6, &rf);
-       rf = (rf & ~0x03) | run_rf3020_freqs[chan - 1].r;
+       rf = (rf & ~0x03) | rt3070_freqs[i].r;
        run_rt3070_rf_write(sc, 6, rf);
 
        /* set Tx0 power */
@@ -3164,12 +3284,166 @@ run_rt3070_set_chan(struct run_softc *sc
        run_rt3070_rf_write(sc, 23, rf);
 
        /* program RF filter */
-       run_rt3070_rf_write(sc, 24, sc->rf24_20mhz);
-       run_rt3070_rf_write(sc, 31, sc->rf24_20mhz);
+       run_rt3070_rf_read(sc, 24, &rf);        /* Tx */
+       rf = (rf & ~0x3f) | sc->rf24_20mhz;
+       run_rt3070_rf_write(sc, 24, rf);
+       run_rt3070_rf_read(sc, 31, &rf);        /* Rx */
+       rf = (rf & ~0x3f) | sc->rf24_20mhz;
+       run_rt3070_rf_write(sc, 31, rf);
+
+       /* enable RF tuning */
+       run_rt3070_rf_read(sc, 7, &rf);
+       run_rt3070_rf_write(sc, 7, rf | 0x01);
+}
+
+static void
+run_rt3572_set_chan(struct run_softc *sc, u_int chan)
+{
+       int8_t txpow1, txpow2;
+       uint32_t tmp;
+       uint8_t rf;
+       int i;
+
+       /* find the settings for this channel (we know it exists) */
+       for (i = 0; rt2860_rf2850[i].chan != chan; i++);
+
+       /* use Tx power values from EEPROM */
+       txpow1 = sc->txpow1[i];
+       txpow2 = sc->txpow2[i];
+
+       if (chan <= 14) {
+               run_bbp_write(sc, 25, sc->bbp25);
+               run_bbp_write(sc, 26, sc->bbp26);
+       } else {
+               /* enable IQ phase correction */
+               run_bbp_write(sc, 25, 0x09);
+               run_bbp_write(sc, 26, 0xff);
+       }
+
+       run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
+       run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
+       run_rt3070_rf_read(sc, 6, &rf);
+       rf  = (rf & ~0x0f) | rt3070_freqs[i].r;
+       rf |= (chan <= 14) ? 0x08 : 0x04;
+       run_rt3070_rf_write(sc, 6, rf);
+
+       /* set PLL mode */
+       run_rt3070_rf_read(sc, 5, &rf);
+       rf &= ~(0x08 | 0x04);
+       rf |= (chan <= 14) ? 0x04 : 0x08;
+       run_rt3070_rf_write(sc, 5, rf);
+
+       /* set Tx power for chain 0 */
+       if (chan <= 14)
+               rf = 0x60 | txpow1;
+       else
+               rf = 0xe0 | (txpow1 & 0xc) << 1 | (txpow1 & 0x3);
+       run_rt3070_rf_write(sc, 12, rf);
+
+       /* set Tx power for chain 1 */
+       if (chan <= 14)
+               rf = 0x60 | txpow2;
+       else
+               rf = 0xe0 | (txpow2 & 0xc) << 1 | (txpow2 & 0x3);
+       run_rt3070_rf_write(sc, 13, rf);
+
+       /* set Tx/Rx streams */
+       run_rt3070_rf_read(sc, 1, &rf);
+       rf &= ~0xfc;
+       if (sc->ntxchains == 1)
+               rf |= 1 << 7 | 1 << 5;  /* 1T: disable Tx chains 2 & 3 */
+       else if (sc->ntxchains == 2)
+               rf |= 1 << 7;           /* 2T: disable Tx chain 3 */
+       if (sc->nrxchains == 1)
+               rf |= 1 << 6 | 1 << 4;  /* 1R: disable Rx chains 2 & 3 */
+       else if (sc->nrxchains == 2)
+               rf |= 1 << 6;           /* 2R: disable Rx chain 3 */
+       run_rt3070_rf_write(sc, 1, rf);
+
+       /* set RF offset */
+       run_rt3070_rf_read(sc, 23, &rf);
+       rf = (rf & ~0x7f) | sc->freq;
+       run_rt3070_rf_write(sc, 23, rf);
+
+       /* program RF filter */
+       rf = sc->rf24_20mhz;
+       run_rt3070_rf_write(sc, 24, rf);        /* Tx */
+       run_rt3070_rf_write(sc, 31, rf);        /* Rx */
+
+       /* enable RF tuning */
+       run_rt3070_rf_read(sc, 7, &rf);
+       rf = (chan <= 14) ? 0xd8 : ((rf & ~0xc8) | 0x14);
+       run_rt3070_rf_write(sc, 7, rf);
+
+       /* TSSI */
+       rf = (chan <= 14) ? 0xc3 : 0xc0;
+       run_rt3070_rf_write(sc, 9, rf);
+
+       /* set loop filter 1 */
+       run_rt3070_rf_write(sc, 10, 0xf1);
+       /* set loop filter 2 */
+       run_rt3070_rf_write(sc, 11, (chan <= 14) ? 0xb9 : 0x00);
+
+       /* set tx_mx2_ic */
+       run_rt3070_rf_write(sc, 15, (chan <= 14) ? 0x53 : 0x43);
+       /* set tx_mx1_ic */
+       if (chan <= 14)
+               rf = 0x48 | sc->txmixgain_2ghz;
+       else
+               rf = 0x78 | sc->txmixgain_5ghz;
+       run_rt3070_rf_write(sc, 16, rf);
+
+       /* set tx_lo1 */
+       run_rt3070_rf_write(sc, 17, 0x23);
+       /* set tx_lo2 */
+       if (chan <= 14)
+               rf = 0x93;
+       else if (chan <= 64)
+               rf = 0xb7;
+       else if (chan <= 128)
+               rf = 0x74;
+       else
+               rf = 0x72;
+       run_rt3070_rf_write(sc, 19, rf);
+
+       /* set rx_lo1 */
+       if (chan <= 14)
+               rf = 0xb3;
+       else if (chan <= 64)
+               rf = 0xf6;
+       else if (chan <= 128)
+               rf = 0xf4;
+       else
+               rf = 0xf3;
+       run_rt3070_rf_write(sc, 20, rf);
+
+       /* set pfd_delay */
+       if (chan <= 14)
+               rf = 0x15;
+       else if (chan <= 64)
+               rf = 0x3d;
+       else
+               rf = 0x01;
+       run_rt3070_rf_write(sc, 25, rf);
+
+       /* set rx_lo2 */
+       run_rt3070_rf_write(sc, 26, (chan <= 14) ? 0x85 : 0x87);
+       /* set ldo_rf_vc */
+       run_rt3070_rf_write(sc, 27, (chan <= 14) ? 0x00 : 0x01);
+       /* set drv_cc */
+       run_rt3070_rf_write(sc, 29, (chan <= 14) ? 0x9b : 0x9f);
+
+       run_read(sc, RT2860_GPIO_CTRL, &tmp);
+       tmp &= ~0x8080;
+       if (chan <= 14)
+               tmp |= 0x80;
+       run_write(sc, RT2860_GPIO_CTRL, tmp);
 
        /* enable RF tuning */
        run_rt3070_rf_read(sc, 7, &rf);
        run_rt3070_rf_write(sc, 7, rf | 0x01);
+
+       run_delay(sc, 2);
 }
 
 static void
@@ -3178,13 +3452,11 @@ run_set_rx_antenna(struct run_softc *sc,
        uint32_t tmp;
 
        if (aux) {
-               run_read(sc, RT2860_PCI_EECTRL, &tmp);
-               run_write(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C);
+               run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0);
                run_read(sc, RT2860_GPIO_CTRL, &tmp);
                run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
        } else {
-               run_read(sc, RT2860_PCI_EECTRL, &tmp);
-               run_write(sc, RT2860_PCI_EECTRL, tmp | RT2860_C);
+               run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1);
                run_read(sc, RT2860_GPIO_CTRL, &tmp);
                run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
        }
@@ -3200,14 +3472,13 @@ run_set_chan(struct run_softc *sc, struc
        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
                return EINVAL;
 
-       if ((sc->mac_rev >> 16) >= 0x3070)
+       if (sc->mac_ver == 0x3572)
+               run_rt3572_set_chan(sc, chan);
+       else if (sc->mac_ver >= 0x3070)
                run_rt3070_set_chan(sc, chan);
        else
                run_rt2870_set_chan(sc, chan);
 
-       /* 802.11a uses a 16 microseconds short interframe space */
-       sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
-
        /* determine channel group */
        if (chan <= 14)
                group = 0;
@@ -3373,7 +3644,7 @@ run_usb_timeout_cb(void *arg, int pendin
        struct run_softc *sc = arg;
        struct ieee80211vap *vap = &sc->sc_rvp->vap;
 
-       RUN_LOCK_ASSERT(sc, MA_OWNED);
+       RUN_LOCK(sc);
 
        if(vap->iv_state == IEEE80211_S_RUN &&
            vap->iv_opmode != IEEE80211_M_STA)
@@ -3384,6 +3655,8 @@ run_usb_timeout_cb(void *arg, int pendin
                ieee80211_cancel_scan(vap);
        } else
                DPRINTF("timeout by unknown cause\n");
+
+       RUN_UNLOCK(sc);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to