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);

Reply via email to