This is based on
http://svnweb.freebsd.org/base?view=revision&revision=257955
For now, my DWA-140 rev B3 is able to
* attach to run(4) and correctly identify MAC address;
* load firmware on ifconfig up;
* blink LED (so I think something is going thru a radio);
* ifconfig down (LED stops blinking).
run0 at uhub3 port 1 "D-Link 11n Adapter" rev 2.00/1.01 addr 6
run0: MAC/BBP RT5392 (rev 0x0222), RF RT5372 (MIMO 2T2R), address
fc:75:16:85:ae:80
$ ifconfig run0
run0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr fc:75:16:85:ae:80
priority: 4
groups: wlan
media: IEEE802.11 autoselect (DS1)
status: no network
ieee80211: nwid ""
But "ifconfig run0 scan" gives nothing and adapter is unable to
associate with AP if directly specified by nwid/wpakey.
Any clue is welcome.
(The following diff requires usbdevs diff I have sent previously).
Index: sys/dev/ic/rt2860reg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/rt2860reg.h,v
retrieving revision 1.31
diff -u -p -r1.31 rt2860reg.h
--- sys/dev/ic/rt2860reg.h 26 Nov 2013 20:33:16 -0000 1.31
+++ sys/dev/ic/rt2860reg.h 6 Jan 2014 13:45:14 -0000
@@ -696,6 +696,7 @@
/* possible flags for RT3020 RF register 1 */
#define RT3070_RF_BLOCK (1 << 0)
+#define RT3070_PLL_PD (1 << 1)
#define RT3070_RX0_PD (1 << 2)
#define RT3070_TX0_PD (1 << 3)
#define RT3070_RX1_PD (1 << 4)
@@ -747,6 +748,15 @@
#define RT3090_DEF_LNA 10
+/* Possible flags for RT5390 RF register 3. */
+#define RT5390_VCOCAL (1 << 7)
+
+/* Possible flags for RT5390 RF register 38. */
+#define RT5390_RX_LO1 (1 << 5)
+
+/* Possible flags for RT5390 RF register 39. */
+#define RT5390_RX_LO2 (1 << 7)
+
/* RT2860 TX descriptor */
struct rt2860_txd {
uint32_t sdp0; /* Segment Data Pointer 0 */
@@ -880,17 +890,19 @@ struct rt2860_rxwi {
#define RT2860_RF3 1
#define RT2860_RF4 3
-#define RT2860_RF_2820 1 /* 2T3R */
-#define RT2860_RF_2850 2 /* dual-band 2T3R */
-#define RT2860_RF_2720 3 /* 1T2R */
-#define RT2860_RF_2750 4 /* dual-band 1T2R */
-#define RT3070_RF_3020 5 /* 1T1R */
-#define RT3070_RF_2020 6 /* b/g */
-#define RT3070_RF_3021 7 /* 1T2R */
-#define RT3070_RF_3022 8 /* 2T2R */
-#define RT3070_RF_3052 9 /* dual-band 2T2R */
-#define RT3070_RF_3320 11 /* 1T1R */
-#define RT3070_RF_3053 13 /* dual-band 3T3R */
+#define RT2860_RF_2820 0x0001 /* 2T3R */
+#define RT2860_RF_2850 0x0002 /* dual-band 2T3R */
+#define RT2860_RF_2720 0x0003 /* 1T2R */
+#define RT2860_RF_2750 0x0004 /* dual-band 1T2R */
+#define RT3070_RF_3020 0x0005 /* 1T1R */
+#define RT3070_RF_2020 0x0006 /* b/g */
+#define RT3070_RF_3021 0x0007 /* 1T2R */
+#define RT3070_RF_3022 0x0008 /* 2T2R */
+#define RT3070_RF_3052 0x0009 /* dual-band 2T2R */
+#define RT3070_RF_3320 0x000b /* 1T1R */
+#define RT3070_RF_3053 0x000d /* dual-band 3T3R */
+#define RT5390_RF_5370 0x5370 /* 1T1R */
+#define RT5390_RF_5372 0x5372 /* 2T2R */
/* USB commands for RT2870 only */
#define RT2870_RESET 1
@@ -1084,63 +1096,94 @@ static const struct rt2860_rate {
{ 105, 0x05 }, \
{ 106, 0x35 }
+#define RT5390_DEF_BBP \
+ { 31, 0x08 }, \
+ { 65, 0x2c }, \
+ { 66, 0x38 }, \
+ { 68, 0x0b }, \
+ { 69, 0x0d }, \
+ { 70, 0x06 }, \
+ { 73, 0x13 }, \
+ { 75, 0x46 }, \
+ { 76, 0x28 }, \
+ { 77, 0x59 }, \
+ { 81, 0x37 }, \
+ { 82, 0x62 }, \
+ { 83, 0x7a }, \
+ { 84, 0x9a }, \
+ { 86, 0x38 }, \
+ { 91, 0x04 }, \
+ { 92, 0x02 }, \
+ { 103, 0xc0 }, \
+ { 104, 0x92 }, \
+ { 105, 0x3c }, \
+ { 106, 0x03 }, \
+ { 128, 0x12 }
+
/*
* Default settings for RF registers; values derived from the reference driver.
*/
-#define RT2860_RF2850 \
- { 1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 }, \
- { 2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 }, \
- { 3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 }, \
- { 4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 }, \
- { 5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 }, \
- { 6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 }, \
- { 7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 }, \
- { 8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 }, \
- { 9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 }, \
- { 10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 }, \
- { 11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 }, \
- { 12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 }, \
- { 13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 }, \
- { 14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 }, \
- { 36, 0x100bb3, 0x130266, 0x056014, 0x001408 }, \
- { 38, 0x100bb3, 0x130267, 0x056014, 0x001404 }, \
- { 40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 }, \
- { 44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 }, \
- { 46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 }, \
- { 48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 }, \
- { 52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 }, \
- { 54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 }, \
- { 56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 }, \
- { 60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 }, \
- { 62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 }, \
- { 64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 }, \
- { 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 }, \
- { 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 }, \
- { 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 }, \
- { 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 }, \
- { 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 }, \
- { 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 }, \
- { 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 }, \
- { 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 }, \
- { 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 }, \
- { 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 }, \
- { 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 }, \
- { 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 }, \
- { 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 }, \
- { 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 }, \
- { 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 }, \
- { 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 }, \
- { 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 }, \
- { 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 }, \
- { 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 }, \
- { 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 }, \
- { 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 }, \
- { 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 }, \
- { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }, \
- { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 }, \
- { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 }, \
- { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 }, \
- { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 }
+#define RT2860_RF2850 \
+ { 1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b }, \
+ { 2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f }, \
+ { 3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b }, \
+ { 4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f }, \
+ { 5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b }, \
+ { 6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f }, \
+ { 7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b }, \
+ { 8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f }, \
+ { 9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b }, \
+ { 10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f }, \
+ { 11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b }, \
+ { 12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f }, \
+ { 13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b }, \
+ { 14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193 }, \
+ { 36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3 }, \
+ { 38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193 }, \
+ { 40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183 }, \
+ { 44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3 }, \
+ { 46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b }, \
+ { 48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b }, \
+ { 52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193 }, \
+ { 54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3 }, \
+ { 56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b }, \
+ { 60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183 }, \
+ { 62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193 }, \
+ { 64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3 }, \
+ { 100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783 }, \
+ { 102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793 }, \
+ { 104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3 }, \
+ { 108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193 }, \
+ { 110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183 }, \
+ { 112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b }, \
+ { 116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3 }, \
+ { 118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193 }, \
+ { 120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183 }, \
+ { 124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193 }, \
+ { 126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b }, \
+ { 128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3 }, \
+ { 132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b }, \
+ { 134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193 }, \
+ { 136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b }, \
+ { 140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183 }, \
+ { 149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7 }, \
+ { 151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187 }, \
+ { 153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f }, \
+ { 157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f }, \
+ { 159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7 }, \
+ { 161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187 }, \
+ { 165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197 }, \
+ { 167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f }, \
+ { 169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327 }, \
+ { 171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307 }, \
+ { 173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f }, \
+ { 184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b }, \
+ { 188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13 }, \
+ { 192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b }, \
+ { 196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23 }, \
+ { 208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13 }, \
+ { 212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b }, \
+ { 216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23 }
#define RT3070_RF3052 \
{ 0xf1, 2, 2 }, \
@@ -1250,3 +1293,122 @@ static const struct rt2860_rate {
{ 29, 0x9b }, \
{ 30, 0x09 }, \
{ 31, 0x10 }
+
+#define RT5390_DEF_RF \
+ { 1, 0x0f }, \
+ { 2, 0x80 }, \
+ { 3, 0x88 }, \
+ { 5, 0x10 }, \
+ { 6, 0xa0 }, \
+ { 7, 0x00 }, \
+ { 10, 0x53 }, \
+ { 11, 0x4a }, \
+ { 12, 0x46 }, \
+ { 13, 0x9f }, \
+ { 14, 0x00 }, \
+ { 15, 0x00 }, \
+ { 16, 0x00 }, \
+ { 18, 0x03 }, \
+ { 19, 0x00 }, \
+ { 20, 0x00 }, \
+ { 21, 0x00 }, \
+ { 22, 0x20 }, \
+ { 23, 0x00 }, \
+ { 24, 0x00 }, \
+ { 25, 0xc0 }, \
+ { 26, 0x00 }, \
+ { 27, 0x09 }, \
+ { 28, 0x00 }, \
+ { 29, 0x10 }, \
+ { 30, 0x10 }, \
+ { 31, 0x80 }, \
+ { 32, 0x80 }, \
+ { 33, 0x00 }, \
+ { 34, 0x07 }, \
+ { 35, 0x12 }, \
+ { 36, 0x00 }, \
+ { 37, 0x08 }, \
+ { 38, 0x85 }, \
+ { 39, 0x1b }, \
+ { 40, 0x0b }, \
+ { 41, 0xbb }, \
+ { 42, 0xd2 }, \
+ { 43, 0x9a }, \
+ { 44, 0x0e }, \
+ { 45, 0xa2 }, \
+ { 46, 0x7b }, \
+ { 47, 0x00 }, \
+ { 48, 0x10 }, \
+ { 49, 0x94 }, \
+ { 52, 0x38 }, \
+ { 53, 0x84 }, \
+ { 54, 0x78 }, \
+ { 55, 0x44 }, \
+ { 56, 0x22 }, \
+ { 57, 0x80 }, \
+ { 58, 0x7f }, \
+ { 59, 0x8f }, \
+ { 60, 0x45 }, \
+ { 61, 0xdd }, \
+ { 62, 0x00 }, \
+ { 63, 0x00 }
+
+#define RT5392_DEF_RF \
+ { 1, 0x17 }, \
+ { 3, 0x88 }, \
+ { 5, 0x10 }, \
+ { 6, 0xe0 }, \
+ { 7, 0x00 }, \
+ { 10, 0x53 }, \
+ { 11, 0x4a }, \
+ { 12, 0x46 }, \
+ { 13, 0x9f }, \
+ { 14, 0x00 }, \
+ { 15, 0x00 }, \
+ { 16, 0x00 }, \
+ { 18, 0x03 }, \
+ { 19, 0x4d }, \
+ { 20, 0x00 }, \
+ { 21, 0x8d }, \
+ { 22, 0x20 }, \
+ { 23, 0x0b }, \
+ { 24, 0x44 }, \
+ { 25, 0x80 }, \
+ { 26, 0x82 }, \
+ { 27, 0x09 }, \
+ { 28, 0x00 }, \
+ { 29, 0x10 }, \
+ { 30, 0x10 }, \
+ { 31, 0x80 }, \
+ { 32, 0x20 }, \
+ { 33, 0xc0 }, \
+ { 34, 0x07 }, \
+ { 35, 0x12 }, \
+ { 36, 0x00 }, \
+ { 37, 0x08 }, \
+ { 38, 0x89 }, \
+ { 39, 0x1b }, \
+ { 40, 0x0f }, \
+ { 41, 0xbb }, \
+ { 42, 0xd5 }, \
+ { 43, 0x9b }, \
+ { 44, 0x0e }, \
+ { 45, 0xa2 }, \
+ { 46, 0x73 }, \
+ { 47, 0x0c }, \
+ { 48, 0x10 }, \
+ { 49, 0x94 }, \
+ { 50, 0x94 }, \
+ { 51, 0x3a }, \
+ { 52, 0x48 }, \
+ { 53, 0x44 }, \
+ { 54, 0x38 }, \
+ { 55, 0x43 }, \
+ { 56, 0xa1 }, \
+ { 57, 0x00 }, \
+ { 58, 0x39 }, \
+ { 59, 0x07 }, \
+ { 60, 0x45 }, \
+ { 61, 0x91 }, \
+ { 62, 0x39 }, \
+ { 63, 0x07 }
Index: sys/dev/usb/if_runvar.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_runvar.h,v
retrieving revision 1.9
diff -u -p -r1.9 if_runvar.h
--- sys/dev/usb/if_runvar.h 15 Apr 2013 09:23:01 -0000 1.9
+++ sys/dev/usb/if_runvar.h 6 Jan 2014 13:45:14 -0000
@@ -144,7 +144,7 @@ struct run_softc {
uint16_t mac_ver;
uint16_t mac_rev;
- uint8_t rf_rev;
+ uint16_t rf_rev;
uint8_t freq;
uint8_t ntxchains;
uint8_t nrxchains;
Index: sys/dev/usb/if_run.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_run.c,v
retrieving revision 1.95
diff -u -p -r1.95 if_run.c
--- sys/dev/usb/if_run.c 30 Sep 2013 05:18:56 -0000 1.95
+++ sys/dev/usb/if_run.c 6 Jan 2014 13:45:15 -0000
@@ -17,7 +17,7 @@
*/
/*-
- * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver.
+ * Ralink Technology RT2700U/RT2800U/RT3000U/RT3900E chipset driver.
* http://www.ralinktech.com/
*/
@@ -158,9 +158,10 @@ static const struct usb_devno run_devs[]
USB_ID(COREGA, RT2870_3),
USB_ID(COREGA, RT3070),
USB_ID(CYBERTAN, RT2870),
- USB_ID(DLINK, DWA127),
USB_ID(DLINK, RT2870),
USB_ID(DLINK, RT3072),
+ USB_ID(DLINK, DWA127),
+ USB_ID(DLINK, DWA140B3),
USB_ID(DLINK2, DWA130),
USB_ID(DLINK2, RT2870_1),
USB_ID(DLINK2, RT2870_2),
@@ -257,6 +258,7 @@ static const struct usb_devno run_devs[]
USB_ID(RALINK, RT3072),
USB_ID(RALINK, RT3370),
USB_ID(RALINK, RT3572),
+ USB_ID(RALINK, RT5370),
USB_ID(RALINK, RT8070),
USB_ID(SAMSUNG2, RT2870_1),
USB_ID(SENAO, RT2870_1),
@@ -338,7 +340,7 @@ int run_rt3070_rf_write(struct run_soft
int run_bbp_read(struct run_softc *, uint8_t, uint8_t *);
int run_bbp_write(struct run_softc *, uint8_t, uint8_t);
int run_mcu_cmd(struct run_softc *, uint8_t, uint16_t);
-const char * run_get_rf(int);
+const char * run_get_rf(uint16_t);
int run_read_eeprom(struct run_softc *);
struct ieee80211_node *run_node_alloc(struct ieee80211com *);
int run_media_change(struct ifnet *);
@@ -374,6 +376,7 @@ void run_set_rx_antenna(struct run_soft
void run_rt2870_set_chan(struct run_softc *, u_int);
void run_rt3070_set_chan(struct run_softc *, u_int);
void run_rt3572_set_chan(struct run_softc *, u_int);
+void run_rt5390_set_chan(struct run_softc *, u_int);
int run_set_chan(struct run_softc *, struct ieee80211_channel *);
void run_enable_tsf_sync(struct run_softc *);
void run_enable_mrr(struct run_softc *);
@@ -388,11 +391,14 @@ void run_updateslot_cb(struct run_softc
int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t);
#endif
int run_bbp_init(struct run_softc *);
+int run_rt5390_bbp_init(struct run_softc *);
int run_rt3070_rf_init(struct run_softc *);
+int run_rt5390_rf_init(struct run_softc *);
int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
uint8_t *);
void run_rt3070_rf_setup(struct run_softc *);
int run_txrx_enable(struct run_softc *);
+void run_adjust_freq_offset(struct run_softc *);
int run_init(struct ifnet *);
void run_stop(struct ifnet *, int);
@@ -417,6 +423,8 @@ static const struct {
uint8_t val;
} rt2860_def_bbp[] = {
RT2860_DEF_BBP
+}, rt5390_def_bbp[] = {
+ RT5390_DEF_BBP
};
static const struct rfprog {
@@ -439,6 +447,10 @@ static const struct {
RT3070_DEF_RF
}, rt3572_def_rf[] = {
RT3572_DEF_RF
+}, rt5390_def_rf[] = {
+ RT5390_DEF_RF
+}, rt5392_def_rf[] = {
+ RT5392_DEF_RF
};
int
@@ -1161,7 +1173,7 @@ b4inc(uint32_t b32, int8_t delta)
}
const char *
-run_get_rf(int rev)
+run_get_rf(uint16_t rev)
{
switch (rev) {
case RT2860_RF_2820: return "RT2820";
@@ -1173,6 +1185,8 @@ run_get_rf(int rev)
case RT3070_RF_3021: return "RT3021";
case RT3070_RF_3022: return "RT3022";
case RT3070_RF_3052: return "RT3052";
+ case RT5390_RF_5370: return "RT5370";
+ case RT5390_RF_5372: return "RT5372";
}
return "unknown";
}
@@ -1210,21 +1224,23 @@ run_read_eeprom(struct run_softc *sc)
ic->ic_myaddr[4] = val & 0xff;
ic->ic_myaddr[5] = val >> 8;
- /* read vendor 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 */
+ if (sc->mac_ver < 0x5390) {
+ /* read vendor BBP 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));
+ 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));
+ }
}
}
@@ -1249,7 +1265,11 @@ run_read_eeprom(struct run_softc *sc)
sc->leds, sc->led[0], sc->led[1], sc->led[2]));
/* read RF information */
- run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
+ if (sc->mac_ver >= 0x5390)
+ run_srom_read(sc, 0x00, &val);
+ else
+ run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
+
if (val == 0xffff) {
DPRINTF(("invalid EEPROM antenna info, using default\n"));
if (sc->mac_ver == 0x3572) {
@@ -1269,11 +1289,15 @@ run_read_eeprom(struct run_softc *sc)
sc->nrxchains = 2;
}
} else {
- sc->rf_rev = (val >> 8) & 0xf;
+ if (sc->mac_ver >= 0x5390) {
+ sc->rf_rev = val;
+ run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
+ } else
+ sc->rf_rev = (val >> 8) & 0xf;
sc->ntxchains = (val >> 4) & 0xf;
sc->nrxchains = val & 0xf;
}
- DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n",
+ DPRINTF(("EEPROM RF rev=0x%04x chains=%dT%dR\n",
sc->rf_rev, sc->ntxchains, sc->nrxchains));
run_srom_read(sc, RT2860_EEPROM_CONFIG, &val);
@@ -1296,16 +1320,28 @@ run_read_eeprom(struct run_softc *sc)
sc->txpow1[i + 0] = (int8_t)(val & 0xff);
sc->txpow1[i + 1] = (int8_t)(val >> 8);
- run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val);
- sc->txpow2[i + 0] = (int8_t)(val & 0xff);
- sc->txpow2[i + 1] = (int8_t)(val >> 8);
+ if (sc->mac_ver != 0x5390) {
+ run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2,
&val);
+ sc->txpow2[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow2[i + 1] = (int8_t)(val >> 8);
+ }
}
/* fix broken Tx power entries */
for (i = 0; i < 14; i++) {
- if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
- sc->txpow1[i] = 5;
- if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
- sc->txpow2[i] = 5;
+ if (sc->mac_ver >= 0x5390) {
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 27)
+ sc->txpow1[i] = 5;
+ } else {
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
+ sc->txpow1[i] = 5;
+ }
+ if (sc->mac_ver > 0x5390) {
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 27)
+ sc->txpow2[i] = 5;
+ } else if (sc->mac_ver < 0x5390) {
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
+ sc->txpow2[i] = 5;
+ }
DPRINTF(("chan %d: power1=%d, power2=%d\n",
rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]));
}
@@ -2419,15 +2455,24 @@ run_select_chan_group(struct run_softc *
run_bbp_write(sc, 62, 0x37 - sc->lna[group]);
run_bbp_write(sc, 63, 0x37 - sc->lna[group]);
run_bbp_write(sc, 64, 0x37 - sc->lna[group]);
- run_bbp_write(sc, 86, 0x00);
+ if (sc->mac_ver < 0x5390)
+ run_bbp_write(sc, 86, 0x00);
if (group == 0) {
if (sc->ext_2ghz_lna) {
- run_bbp_write(sc, 82, 0x62);
- run_bbp_write(sc, 75, 0x46);
+ if (sc->mac_ver >= 0x5390)
+ run_bbp_write(sc, 75, 0x52);
+ else {
+ run_bbp_write(sc, 82, 0x62);
+ run_bbp_write(sc, 75, 0x46);
+ }
} else {
- run_bbp_write(sc, 82, 0x84);
- run_bbp_write(sc, 75, 0x50);
+ if (sc->mac_ver >= 0x5390)
+ run_bbp_write(sc, 75, 0x50);
+ else {
+ run_bbp_write(sc, 82, 0x84);
+ run_bbp_write(sc, 75, 0x50);
+ }
}
} else {
if (sc->mac_ver == 0x3572)
@@ -2748,6 +2793,116 @@ run_rt3572_set_chan(struct run_softc *sc
}
void
+run_rt5390_set_chan(struct run_softc *sc, u_int chan)
+{
+ int8_t txpow1, txpow2;
+ 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];
+
+ run_rt3070_rf_write(sc, 8, rt3070_freqs[i].n);
+ run_rt3070_rf_write(sc, 9, rt3070_freqs[i].k & 0x0f);
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf = (rf & ~0x03) | (rt3070_freqs[i].r & 0x03);
+ run_rt3070_rf_write(sc, 11, rf);
+
+ run_rt3070_rf_read(sc, 49, &rf);
+ rf = (rf & ~0x3f) | (txpow1 & 0x3f);
+ /* The valid range of the RF R49 is 0x00 to 0x27. */
+ if ((rf & 0x3f) > 0x27)
+ rf = (rf & ~0x3f) | 0x27;
+ run_rt3070_rf_write(sc, 49, rf);
+
+ if (sc->mac_ver == 0x5392) {
+ run_rt3070_rf_read(sc, 50, &rf);
+ rf = (rf & ~0x3f) | (txpow2 & 0x3f);
+ /* The valid range of the RF R50 is 0x00 to 0x27. */
+ if ((rf & 0x3f) > 0x27)
+ rf = (rf & ~0x3f) | 0x27;
+ run_rt3070_rf_write(sc, 50, rf);
+ }
+
+ run_rt3070_rf_read(sc, 1, &rf);
+ rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD;
+ if (sc->mac_ver == 0x5392)
+ rf |= RT3070_RX1_PD | RT3070_TX1_PD;
+ run_rt3070_rf_write(sc, 1, rf);
+
+ if (sc->mac_ver != 0x5392) {
+ run_rt3070_rf_read(sc, 2, &rf);
+ rf |= 0x80;
+ run_rt3070_rf_write(sc, 2, rf);
+ DELAY(10000);
+ rf &= 0x7f;
+ run_rt3070_rf_write(sc, 2, rf);
+ }
+
+ run_adjust_freq_offset(sc);
+
+ if (sc->mac_ver == 0x5392) {
+ /* Fix for RT5392C. */
+ if (sc->mac_rev >= 0x0223) {
+ if ((chan >= 1) && (chan <= 4))
+ rf = 0x0f;
+ else if ((chan >= 5) && (chan <= 7))
+ rf = 0x0e;
+ else if ((chan >= 8) && (chan <= 14))
+ rf = 0x0d;
+ run_rt3070_rf_write(sc, 23, rf);
+
+ if ((chan >= 1) && (chan <= 4))
+ rf = 0x0c;
+ else if (chan == 5)
+ rf = 0x0b;
+ else if ((chan >= 6) && (chan <= 7))
+ rf = 0x0a;
+ else if ((chan >= 8) && (chan <= 10))
+ rf = 0x09;
+ else if ((chan >= 11) && (chan <= 14))
+ rf = 0x08;
+ run_rt3070_rf_write(sc, 59, rf);
+ } else {
+ if ((chan >= 1) && (chan <= 11))
+ rf = 0x0f;
+ else if ((chan >= 12) && (chan <= 14))
+ rf = 0x0b;
+ run_rt3070_rf_write(sc, 59, rf);
+ }
+ } else {
+ /* Fix for RT5390F. */
+ if (sc->mac_rev >= 0x0502) {
+ if ((chan >= 1) && (chan <= 11))
+ rf = 0x43;
+ else if ((chan >= 12) && (chan <= 14))
+ rf = 0x23;
+ run_rt3070_rf_write(sc, 55, rf);
+
+ if ((chan >= 1) && (chan <= 11))
+ rf = 0x0f;
+ else if (chan == 12)
+ rf = 0x0d;
+ else if ((chan >= 13) && (chan <= 14))
+ rf = 0x0b;
+ run_rt3070_rf_write(sc, 59, rf);
+ } else {
+ run_rt3070_rf_write(sc, 55, 0x44);
+ run_rt3070_rf_write(sc, 59, 0x8f);
+ }
+ }
+
+ /* Enable VCO calibration. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf |= RT5390_VCOCAL;
+ run_rt3070_rf_write(sc, 3, rf);
+}
+
+void
run_set_agc(struct run_softc *sc, uint8_t agc)
{
uint8_t bbp;
@@ -2767,13 +2922,22 @@ void
run_set_rx_antenna(struct run_softc *sc, int aux)
{
uint32_t tmp;
+ uint8_t bbp152;
- run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, !aux);
- run_read(sc, RT2860_GPIO_CTRL, &tmp);
- tmp &= ~0x0808;
- if (aux)
- tmp |= 0x08;
- run_write(sc, RT2860_GPIO_CTRL, tmp);
+ if (sc->rf_rev == RT5390_RF_5370) {
+ run_bbp_read(sc, 152, &bbp152);
+ bbp152 &= ~0x80;
+ if (aux)
+ bbp152 |= 0x80;
+ run_bbp_write(sc, 152, bbp152);
+ } else {
+ run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, !aux);
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ tmp &= ~0x0808;
+ if (aux)
+ tmp |= 0x08;
+ run_write(sc, RT2860_GPIO_CTRL, tmp);
+ }
}
int
@@ -2786,7 +2950,9 @@ run_set_chan(struct run_softc *sc, struc
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return EINVAL;
- if (sc->mac_ver == 0x3572)
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_set_chan(sc, chan);
+ else if (sc->mac_ver == 0x3572)
run_rt3572_set_chan(sc, chan);
else if (sc->mac_ver >= 0x3070)
run_rt3070_set_chan(sc, chan);
@@ -2963,9 +3129,13 @@ run_bbp_init(struct run_softc *sc)
return ETIMEDOUT;
/* initialize BBP registers to default values */
- for (i = 0; i < nitems(rt2860_def_bbp); i++) {
- run_bbp_write(sc, rt2860_def_bbp[i].reg,
- rt2860_def_bbp[i].val);
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_bbp_init(sc);
+ else {
+ for (i = 0; i < nitems(rt2860_def_bbp); i++) {
+ run_bbp_write(sc, rt2860_def_bbp[i].reg,
+ rt2860_def_bbp[i].val);
+ }
}
/* fix BBP84 for RT2860E */
@@ -2984,6 +3154,36 @@ run_bbp_init(struct run_softc *sc)
}
int
+run_rt5390_bbp_init(struct run_softc *sc)
+{
+ int i;
+ uint8_t bbp4;
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp4);
+ run_bbp_write(sc, 4, bbp4 | 0x40);
+
+ for (i = 0; i < nitems(rt5390_def_bbp); i++) {
+ run_bbp_write(sc, rt5390_def_bbp[i].reg,
+ rt5390_def_bbp[i].val);
+ }
+ if (sc->mac_ver == 0x5392) {
+ run_bbp_write(sc, 88, 0x90);
+ run_bbp_write(sc, 95, 0x9a);
+ run_bbp_write(sc, 98, 0x12);
+ run_bbp_write(sc, 106, 0x12);
+ run_bbp_write(sc, 134, 0xd0);
+ run_bbp_write(sc, 135, 0xf6);
+ run_bbp_write(sc, 148, 0x84);
+ }
+
+ /* Disable hardware antenna diversity. */
+ if (sc->mac_ver == 0x5390)
+ run_bbp_write(sc, 154, 0);
+ return 0;
+}
+
+int
run_rt3070_rf_init(struct run_softc *sc)
{
uint32_t tmp;
@@ -3120,6 +3320,63 @@ run_rt3070_rf_init(struct run_softc *sc)
}
int
+run_rt5390_rf_init(struct run_softc *sc)
+{
+ uint32_t tmp;
+ uint8_t rf;
+ int i;
+
+ if (sc->mac_ver == 0x5392)
+ run_rt3070_rf_write(sc, 2, 0x80);
+ else {
+ run_rt3070_rf_read(sc, 2, &rf);
+ /* Toggle RF R2 to initiate calibration. */
+ run_rt3070_rf_write(sc, 2, rf | 0x80);
+ DELAY(10000);
+ run_rt3070_rf_write(sc, 2, rf & ~0x80);
+ }
+
+ /* Initialize RF registers to default value. */
+ if (sc->mac_ver == 0x5392) {
+ for (i = 0; i < nitems(rt5392_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5392_def_rf[i].reg,
+ rt5392_def_rf[i].val);
+ }
+ if (sc->mac_rev >= 0x0223) {
+ run_rt3070_rf_write(sc, 23, 0x0f);
+ run_rt3070_rf_write(sc, 24, 0x3e);
+ run_rt3070_rf_write(sc, 51, 0x32);
+ run_rt3070_rf_write(sc, 53, 0x22);
+ run_rt3070_rf_write(sc, 56, 0xc1);
+ run_rt3070_rf_write(sc, 59, 0x0f);
+ }
+ } else {
+ for (i = 0; i < nitems(rt5390_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5390_def_rf[i].reg,
+ rt5390_def_rf[i].val);
+ }
+ if (sc->mac_rev >= 0x0502) {
+ run_rt3070_rf_write(sc, 6, 0xe0);
+ run_rt3070_rf_write(sc, 25, 0x80);
+ run_rt3070_rf_write(sc, 46, 0x73);
+ run_rt3070_rf_write(sc, 53, 0x00);
+ run_rt3070_rf_write(sc, 56, 0x42);
+ run_rt3070_rf_write(sc, 61, 0xd1);
+ }
+ }
+
+ sc->rf24_20mhz = 0x1f; /* default value */
+ sc->rf24_40mhz = 0x2f; /* default value */
+
+ if (sc->mac_rev < 0x0211)
+ run_rt3070_rf_write(sc, 27, 0x3);
+
+ run_read(sc, RT3070_OPT_14, &tmp);
+ run_write(sc, RT3070_OPT_14, tmp | 1);
+ return 0;
+}
+
+int
run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
uint8_t *val)
{
@@ -3190,7 +3447,45 @@ run_rt3070_rf_setup(struct run_softc *sc
uint8_t bbp, rf;
int i;
- if (sc->mac_ver == 0x3572) {
+ if (sc->mac_ver >= 0x5390) {
+ if (sc->mac_rev >= 0x0211) {
+ /* Enable DC filter. */
+ run_bbp_write(sc, 103, 0xc0);
+
+ /* Improve power consumption. */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ run_bbp_read(sc, 138, &bbp);
+ if (sc->ntxchains == 1)
+ bbp |= 0x20; /* turn off DAC1 */
+ if (sc->nrxchains == 1)
+ bbp &= ~0x02; /* turn off ADC1 */
+ run_bbp_write(sc, 138, bbp);
+
+ run_rt3070_rf_read(sc, 38, &rf);
+ run_rt3070_rf_write(sc, 38, rf & ~RT5390_RX_LO1);
+
+ run_rt3070_rf_read(sc, 39, &rf);
+ run_rt3070_rf_write(sc, 39, rf & ~RT5390_RX_LO2);
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp);
+ run_bbp_write(sc, 4, bbp | 0x40);
+
+ run_rt3070_rf_read(sc, 30, &rf);
+ rf = (rf & ~0x18) | 0x10;
+ run_rt3070_rf_write(sc, 30, rf);
+
+ run_write(sc, RT2860_TX_SW_CFG1, 0);
+ if (sc->mac_rev < 0x0211) {
+ run_write(sc, RT2860_TX_SW_CFG2,
+ sc->patch_dac ? 0x2c : 0x0f);
+ } else
+ run_write(sc, RT2860_TX_SW_CFG2, 0);
+
+ } else if (sc->mac_ver == 0x3572) {
/* enable DC filter */
if (sc->mac_rev >= 0x0201)
run_bbp_write(sc, 103, 0xc0);
@@ -3255,7 +3550,7 @@ run_rt3070_rf_setup(struct run_softc *sc
}
/* initialize RF registers from ROM for >=RT3071*/
- if (sc->mac_ver >= 0x3071) {
+ if (sc->mac_ver >= 0x3071 && sc->mac_ver < 0x5390) {
for (i = 0; i < 10; i++) {
if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
continue;
@@ -3309,6 +3604,20 @@ run_txrx_enable(struct run_softc *sc)
return 0;
}
+void
+run_adjust_freq_offset(struct run_softc * sc)
+{
+ uint8_t rf, tmp;
+
+ run_rt3070_rf_read(sc, 17, &rf);
+ tmp = rf;
+ rf = (rf & ~0x7f) | (sc->freq & 0x7f);
+ rf = MIN(rf, 0x5f);
+
+ if (tmp != rf)
+ run_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf);
+}
+
int
run_init(struct ifnet *ifp)
{
@@ -3399,7 +3708,14 @@ run_init(struct ifnet *ifp)
run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344);
run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa);
- if (sc->mac_ver >= 0x3070) {
+ if (sc->mac_ver == 0x5392) {
+ run_write(sc, RT2860_TX_SW_CFG0, 0x00000404);
+ run_write(sc, RT2860_MAX_LEN_CFG, 0x00002fff);
+ run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980);
+ run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322);
+ } else if (sc->mac_ver == 0x5390) {
+ run_write(sc, RT2860_TX_SW_CFG0, 0x00000404);
+ } else if (sc->mac_ver >= 0x3070) {
/* set delay of PA_PE assertion to 1us (unit of 0.25us) */
run_write(sc, RT2860_TX_SW_CFG0,
4 << RT2860_DLY_PAPE_EN_SHIFT);
@@ -3453,14 +3769,16 @@ run_init(struct ifnet *ifp)
run_write(sc, RT2860_WMM_TXOP1_CFG, 48 << 16 | 96);
/* write vendor-specific BBP values (from EEPROM) */
- for (i = 0; i < 8; i++) {
- if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
- continue;
- run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
+ if (sc->mac_ver < 0x5390) {
+ for (i = 0; i < 8; i++) {
+ if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
+ continue;
+ run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
+ }
}
/* select Main antenna for 1T1R devices */
- if (sc->rf_rev == RT3070_RF_3020)
+ if (sc->rf_rev == RT3070_RF_3020 || sc->rf_rev == RT5390_RF_5370)
run_set_rx_antenna(sc, 0);
/* send LEDs operating mode to microcontroller */
@@ -3468,7 +3786,9 @@ run_init(struct ifnet *ifp)
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]);
- if (sc->mac_ver >= 0x3070)
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_rf_init(sc);
+ else if (sc->mac_ver >= 0x3070)
run_rt3070_rf_init(sc);
/* disable non-existing Rx chains */
@@ -3552,6 +3872,24 @@ run_stop(struct ifnet *ifp, int disable)
/* wait for all queued asynchronous commands to complete */
usb_wait_task(sc->sc_udev, &sc->sc_task);
splx(s);
+
+ /* Disable Tx/Rx DMA. */
+ if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
+ return;
+ tmp &= ~(RT2860_RX_DMA_EN | RT2860_TX_DMA_EN);
+ run_write(sc, RT2860_WPDMA_GLO_CFG, tmp);
+
+ for (ntries = 0; ntries < 100; ntries++) {
+ if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
+ return;
+ if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
+ break;
+ DELAY(10000);
+ }
+ if (ntries == 100) {
+ printf("%s: timeout waiting for DMA engine\n",
sc->sc_dev.dv_xname);
+ return;
+ }
/* disable Tx/Rx */
run_read(sc, RT2860_MAC_SYS_CTRL, &tmp);