Browse Source

mac80211: add a bunch of rt2x00 specific changes

Backport some rt2x00 specific changes from
wireless-testing/master-2013-08-26 to add
support for RT3573 based devices.

Also refresh the rt2x00 specific patches.

Signed-off-by: Gabor Juhos <[email protected]>

SVN-Revision: 37843
Gabor Juhos 12 years ago
parent
commit
6c29525f42

+ 1 - 1
package/kernel/mac80211/Makefile

@@ -1361,7 +1361,7 @@ config-$(call config_package,rt2800-pci) += RT2800PCI
 config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290
 
 config-$(call config_package,rt2800-usb) += RT2800USB
-config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT53XX RT2800USB_RT55XX
+config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX
 
 config-$(call config_package,iwl-legacy) += IWLEGACY
 config-$(call config_package,iwl3945) += IWL3945

+ 3300 - 0
package/kernel/mac80211/patches/301-pending_work-rt2x00.patch

@@ -0,0 +1,3300 @@
+Contains the following changes from wireless-testing/master-2013-08-26:
+
+  commit 8951b79a4e6d8228babf56ae79a345e4abc5ac82
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 11:25:52 2013 +0200
+
+      rt2x00: rt2800lib: introduce rt2800_eeprom_word enum
+
+  commit 3e38d3daf881a78ac13e93504a8ac5777040797e
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 11:25:53 2013 +0200
+
+      rt2x00: rt2800lib: introduce local EEPROM access functions
+
+  commit 022138ca93f016374d5d3f69c070c75596c5ecac
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 11:25:54 2013 +0200
+
+      rt2x00: rt2800lib: introduce rt2800_eeprom_read_from_array helper
+
+  commit 379448fe34e289fdcc473399d4f6cac19e757fb8
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 11:25:55 2013 +0200
+
+      rt2x00: rt2800lib: introduce rt2800_eeprom_word_index helper
+
+  commit fa31d157f83ef71b6530aacf0400bafe7816acbd
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 11:25:56 2013 +0200
+
+      rt2x00: rt2800lib: add EEPROM map for the RT3593 chipset
+
+  commit 1706d15d82f4a579119b419cd673987af60f1d9b
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:16 2013 +0200
+
+      rt2x00: rt2800lib: add MAC register initialization for RT3593
+
+  commit b189a1814135bc52f516ca61a1fa161914d57a54
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:17 2013 +0200
+
+      rt2x00: rt2800lib: add BBP register initialization for RT3593
+
+  commit ab7078ac3d920e0d49b17e92f327f3ada25600e8
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:18 2013 +0200
+
+      rt2x00: rt2800lib: add RFCSR register initialization for RT3593
+
+  commit d63f7e8ca560dc9a76a15c323cb9cba14b25f430
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:19 2013 +0200
+
+      rt2x00: rt2800lib: add BBP post initialization for RT3593
+
+  commit 34542ff5a665061d548c3f860807df341f718adf
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:20 2013 +0200
+
+      rt2x00: rt2800lib: add TX power configuration for RT3593
+
+  commit 4788ac1e4842d8ef46ee620cfccf96c426043177
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:21 2013 +0200
+
+      rt2x00: rt2800lib: fix BBP1_TX_ANTENNA field configuration for 3T devices
+
+  commit 5cddb3c2d5102d9a6b1b809e1518da54c8be8296
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:22 2013 +0200
+
+      rt2x00: rt2800lib: fix antenna configuration for RT3593
+
+  commit 97aa03f15e83174df74aa468eea127c5cee480f0
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:23 2013 +0200
+
+      rt2x00: rt2800lib: add rt2800_txpower_to_dev helper
+
+  commit fc739cfe0f305647677edbf99a76d9ece96e3795
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:24 2013 +0200
+
+      rt2x00: rt2800lib: fix default TX power values for RT3593
+
+  commit a3f1625dae58f06c5df1ec0094b275e9a46fd8b3
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:25 2013 +0200
+
+      rt2x00: rt2800lib: introduce rt2800_get_txmixer_gain_{24,5}g helpers
+
+  commit 6316c786cc8aff762530ea740233bf2da10fea33
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:26 2013 +0200
+
+      rt2x00: rt2800lib: hardcode TX mixer gain values for RT3593
+
+  commit f36bb0ca1be5bcb7148ad32263626f8609dfc0d7
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:27 2013 +0200
+
+      rt2x00: rt2800lib: fix LNA_A[12] gain values for RT3593
+
+  commit c0a14369ebd3e7940e70e397ecc3dd7eaf81e9ab
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:28 2013 +0200
+
+      rt2x00: rt2800lib: add default_power3 field for three-chain devices
+
+  commit c8b9d3dc83cab569de6054a10e355a143e2b52a0
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:29 2013 +0200
+
+      rt2x00: rt2800lib: add rf_vals for RF3053
+
+  commit f42b046578efb018064302fd9b66586f5da7d75b
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:30 2013 +0200
+
+      rt2x00: rt2800lib: add channel configuration for RF3053
+
+  commit 1095df07bfc5924e100f1748e6ebc9e5a5881565
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:31 2013 +0200
+
+      rt2x00: rt2800lib: enable VCO recalibration for RF3053
+
+  commit 0f5af26a49c8d6a50ecec2f1b66174069c9f9581
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:32 2013 +0200
+
+      rt2x00: rt2800lib: enable RF3053 support
+
+  commit 2dc2bd2f8aa8eb79184fb3c7e5f530006500897f
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:33 2013 +0200
+
+      rt2x00: rt2800lib: enable RT3593 support
+
+  commit 65d3c0d5cffb9f1227927544e418a9ac231eae42
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:34 2013 +0200
+
+      rt2x00: rt2800usb: use correct [RT]XWI size for RT3593
+
+  commit d02433d15566f542e42e3c469dfade0de332dc7b
+  Author: Gabor Juhos <[email protected]>
+  Date:   Mon Jul 8 16:08:35 2013 +0200
+
+      rt2x00: rt2800usb: add USB device ID for Linksys AE3000
+
+  commit 637065267eab4817c0b06cbf3c7fc80842acab99
+  Author: Xose Vazquez Perez <[email protected]>
+  Date:   Tue Jul 23 14:55:15 2013 +0200
+
+      wireless: rt2x00: rt2800usb: add RT3573 devices
+
+  commit ae1b1c5dcdef1ebd4b37a7d56ad767add757a660
+  Author: Gabor Juhos <[email protected]>
+  Date:   Fri Aug 16 10:23:29 2013 +0200
+
+      rt2x00: rt2800lib: introduce rt2800_get_txwi_rxwi_size helper
+
+  commit 41caa760d6acaf47cbd44c3d78307fb9be089111
+  Author: Gabor Juhos <[email protected]>
+  Date:   Fri Aug 16 10:23:30 2013 +0200
+
+      rt2x00: rt2800pci: fix AUX_CTRL register setup for RT3090/3390/3593/5592
+
+  commit 91a3fa39ddf2f85a15cb20ccc3a54c1f0497af1e
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 00:15:49 2013 +0200
+
+      rt2x00: rt2800: rename HW_BEACON_OFFSET macro
+
+  commit 77f7c0f3b8f2d464e841c5c35f3da8b4999a885c
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 00:15:50 2013 +0200
+
+      rt2x00: rt2800lib: pass beacon index to rt2800_clear_beacon_register
+
+  commit c1fada4e5e53d88a8edd3ff01cee9d316cbf6025
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 14:09:28 2013 +0200
+
+      rt2x00: rt2800lib: fix frequency offset boundary calculation
+
+  commit 6af1bdccabe956a08a37f2ae049d37307ec0c91c
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 14:09:29 2013 +0200
+
+      rt2x00: rt2800lib: optimize frequency offset adjustment
+
+  commit 76773f301f2210dcc20c466aebda7118062673eb
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 14:09:30 2013 +0200
+
+      rt2x00: rt2800lib: use a MCU command for frequency adjustment on USB devices
+
+  commit 8d38eca8e089179b6858ca5f3ea03f571a5892a5
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 14:09:31 2013 +0200
+
+      rt2x00: rt2800lib: use step-by-step frequency offset adjustment on MMIO devices
+
+  commit 3f1b8739a498c7570ca2fae6c49fd1561ef2358c
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 14:09:32 2013 +0200
+
+      rt2x00: rt2800lib: move rt2800_adjust_freq_offset function
+
+  commit e979a8ab204edbf7b0815162109ee9c85e4d7ea5
+  Author: Gabor Juhos <[email protected]>
+  Date:   Sat Aug 17 14:09:33 2013 +0200
+
+      rt2x00: rt2800lib: adjust frequency offset for RF3053
+
+  commit 21c6af6b69b609b7934caaccda1b4535dceb402c
+  Author: Gabor Juhos <[email protected]>
+  Date:   Thu Aug 22 20:53:21 2013 +0200
+
+      rt2x00: rt2800lib: add rt2800_hw_beacon_base helper
+
+  commit 634b80595fef79071d82bc231b7f82c4f808a1e8
+  Author: Gabor Juhos <[email protected]>
+  Date:   Thu Aug 22 20:53:22 2013 +0200
+
+      rt2x00: rt2800lib: don't hardcode beacon offsets
+
+  commit 6e956da2027c767859128b9bfef085cf2a8e233b
+  Author: Stanislaw Gruszka <[email protected]>
+  Date:   Mon Aug 26 15:18:53 2013 +0200
+
+      rt2800: fix wrong TX power compensation
+
+---
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -174,6 +174,12 @@ config RT2800USB_RT35XX
+ 	  rt2800usb driver.
+ 	  Supported chips: RT3572
+ 
++config RT2800USB_RT3573
++	bool "rt2800usb - Include support for rt3573 devices (EXPERIMENTAL)"
++	---help---
++	  This enables support for RT3573 chipset based wireless USB devices
++	  in the rt2800usb driver.
++
+ config RT2800USB_RT53XX
+        bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
+        ---help---
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -88,6 +88,7 @@
+ #define REV_RT3071E			0x0211
+ #define REV_RT3090E			0x0211
+ #define REV_RT3390E			0x0211
++#define REV_RT3593E			0x0211
+ #define REV_RT5390F			0x0502
+ #define REV_RT5390R			0x1502
+ #define REV_RT5592C			0x0221
+@@ -1082,6 +1083,15 @@
+ #define TX_PWR_CFG_0_9MBS		FIELD32(0x00f00000)
+ #define TX_PWR_CFG_0_12MBS		FIELD32(0x0f000000)
+ #define TX_PWR_CFG_0_18MBS		FIELD32(0xf0000000)
++/* bits for 3T devices */
++#define TX_PWR_CFG_0_CCK1_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_0_CCK1_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_0_CCK5_CH0		FIELD32(0x00000f00)
++#define TX_PWR_CFG_0_CCK5_CH1		FIELD32(0x0000f000)
++#define TX_PWR_CFG_0_OFDM6_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_0_OFDM6_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_0_OFDM12_CH0		FIELD32(0x0f000000)
++#define TX_PWR_CFG_0_OFDM12_CH1		FIELD32(0xf0000000)
+ 
+ /*
+  * TX_PWR_CFG_1:
+@@ -1095,6 +1105,15 @@
+ #define TX_PWR_CFG_1_MCS1		FIELD32(0x00f00000)
+ #define TX_PWR_CFG_1_MCS2		FIELD32(0x0f000000)
+ #define TX_PWR_CFG_1_MCS3		FIELD32(0xf0000000)
++/* bits for 3T devices */
++#define TX_PWR_CFG_1_OFDM24_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_1_OFDM24_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_1_OFDM48_CH0		FIELD32(0x00000f00)
++#define TX_PWR_CFG_1_OFDM48_CH1		FIELD32(0x0000f000)
++#define TX_PWR_CFG_1_MCS0_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_1_MCS0_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_1_MCS2_CH0		FIELD32(0x0f000000)
++#define TX_PWR_CFG_1_MCS2_CH1		FIELD32(0xf0000000)
+ 
+ /*
+  * TX_PWR_CFG_2:
+@@ -1108,6 +1127,15 @@
+ #define TX_PWR_CFG_2_MCS9		FIELD32(0x00f00000)
+ #define TX_PWR_CFG_2_MCS10		FIELD32(0x0f000000)
+ #define TX_PWR_CFG_2_MCS11		FIELD32(0xf0000000)
++/* bits for 3T devices */
++#define TX_PWR_CFG_2_MCS4_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_2_MCS4_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_2_MCS6_CH0		FIELD32(0x00000f00)
++#define TX_PWR_CFG_2_MCS6_CH1		FIELD32(0x0000f000)
++#define TX_PWR_CFG_2_MCS8_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_2_MCS8_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_2_MCS10_CH0		FIELD32(0x0f000000)
++#define TX_PWR_CFG_2_MCS10_CH1		FIELD32(0xf0000000)
+ 
+ /*
+  * TX_PWR_CFG_3:
+@@ -1121,6 +1149,15 @@
+ #define TX_PWR_CFG_3_UKNOWN2		FIELD32(0x00f00000)
+ #define TX_PWR_CFG_3_UKNOWN3		FIELD32(0x0f000000)
+ #define TX_PWR_CFG_3_UKNOWN4		FIELD32(0xf0000000)
++/* bits for 3T devices */
++#define TX_PWR_CFG_3_MCS12_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_3_MCS12_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_3_MCS14_CH0		FIELD32(0x00000f00)
++#define TX_PWR_CFG_3_MCS14_CH1		FIELD32(0x0000f000)
++#define TX_PWR_CFG_3_STBC0_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_3_STBC0_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_3_STBC2_CH0		FIELD32(0x0f000000)
++#define TX_PWR_CFG_3_STBC2_CH1		FIELD32(0xf0000000)
+ 
+ /*
+  * TX_PWR_CFG_4:
+@@ -1130,6 +1167,11 @@
+ #define TX_PWR_CFG_4_UKNOWN6		FIELD32(0x000000f0)
+ #define TX_PWR_CFG_4_UKNOWN7		FIELD32(0x00000f00)
+ #define TX_PWR_CFG_4_UKNOWN8		FIELD32(0x0000f000)
++/* bits for 3T devices */
++#define TX_PWR_CFG_3_STBC4_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_3_STBC4_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_3_STBC6_CH0		FIELD32(0x00000f00)
++#define TX_PWR_CFG_3_STBC6_CH1		FIELD32(0x0000f000)
+ 
+ /*
+  * TX_PIN_CFG:
+@@ -1451,6 +1493,81 @@
+  */
+ #define EXP_ACK_TIME			0x1380
+ 
++/* TX_PWR_CFG_5 */
++#define TX_PWR_CFG_5			0x1384
++#define TX_PWR_CFG_5_MCS16_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_5_MCS16_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_5_MCS16_CH2		FIELD32(0x00000f00)
++#define TX_PWR_CFG_5_MCS18_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_5_MCS18_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_5_MCS18_CH2		FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_6 */
++#define TX_PWR_CFG_6			0x1388
++#define TX_PWR_CFG_6_MCS20_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_6_MCS20_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_6_MCS20_CH2		FIELD32(0x00000f00)
++#define TX_PWR_CFG_6_MCS22_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_6_MCS22_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_6_MCS22_CH2		FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_0_EXT */
++#define TX_PWR_CFG_0_EXT		0x1390
++#define TX_PWR_CFG_0_EXT_CCK1_CH2	FIELD32(0x0000000f)
++#define TX_PWR_CFG_0_EXT_CCK5_CH2	FIELD32(0x00000f00)
++#define TX_PWR_CFG_0_EXT_OFDM6_CH2	FIELD32(0x000f0000)
++#define TX_PWR_CFG_0_EXT_OFDM12_CH2	FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_1_EXT */
++#define TX_PWR_CFG_1_EXT		0x1394
++#define TX_PWR_CFG_1_EXT_OFDM24_CH2	FIELD32(0x0000000f)
++#define TX_PWR_CFG_1_EXT_OFDM48_CH2	FIELD32(0x00000f00)
++#define TX_PWR_CFG_1_EXT_MCS0_CH2	FIELD32(0x000f0000)
++#define TX_PWR_CFG_1_EXT_MCS2_CH2	FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_2_EXT */
++#define TX_PWR_CFG_2_EXT		0x1398
++#define TX_PWR_CFG_2_EXT_MCS4_CH2	FIELD32(0x0000000f)
++#define TX_PWR_CFG_2_EXT_MCS6_CH2	FIELD32(0x00000f00)
++#define TX_PWR_CFG_2_EXT_MCS8_CH2	FIELD32(0x000f0000)
++#define TX_PWR_CFG_2_EXT_MCS10_CH2	FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_3_EXT */
++#define TX_PWR_CFG_3_EXT		0x139c
++#define TX_PWR_CFG_3_EXT_MCS12_CH2	FIELD32(0x0000000f)
++#define TX_PWR_CFG_3_EXT_MCS14_CH2	FIELD32(0x00000f00)
++#define TX_PWR_CFG_3_EXT_STBC0_CH2	FIELD32(0x000f0000)
++#define TX_PWR_CFG_3_EXT_STBC2_CH2	FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_4_EXT */
++#define TX_PWR_CFG_4_EXT		0x13a0
++#define TX_PWR_CFG_4_EXT_STBC4_CH2	FIELD32(0x0000000f)
++#define TX_PWR_CFG_4_EXT_STBC6_CH2	FIELD32(0x00000f00)
++
++/* TX_PWR_CFG_7 */
++#define TX_PWR_CFG_7			0x13d4
++#define TX_PWR_CFG_7_OFDM54_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_7_OFDM54_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_7_OFDM54_CH2		FIELD32(0x00000f00)
++#define TX_PWR_CFG_7_MCS7_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_7_MCS7_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_7_MCS7_CH2		FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_8 */
++#define TX_PWR_CFG_8			0x13d8
++#define TX_PWR_CFG_8_MCS15_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_8_MCS15_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_8_MCS15_CH2		FIELD32(0x00000f00)
++#define TX_PWR_CFG_8_MCS23_CH0		FIELD32(0x000f0000)
++#define TX_PWR_CFG_8_MCS23_CH1		FIELD32(0x00f00000)
++#define TX_PWR_CFG_8_MCS23_CH2		FIELD32(0x0f000000)
++
++/* TX_PWR_CFG_9 */
++#define TX_PWR_CFG_9			0x13dc
++#define TX_PWR_CFG_9_STBC7_CH0		FIELD32(0x0000000f)
++#define TX_PWR_CFG_9_STBC7_CH1		FIELD32(0x000000f0)
++#define TX_PWR_CFG_9_STBC7_CH2		FIELD32(0x00000f00)
++
+ /*
+  * RX_FILTER_CFG: RX configuration register.
+  */
+@@ -1902,11 +2019,13 @@ struct mac_iveiv_entry {
+ #define HW_BEACON_BASE6			0x5dc0
+ #define HW_BEACON_BASE7			0x5bc0
+ 
+-#define HW_BEACON_OFFSET(__index) \
++#define HW_BEACON_BASE(__index) \
+ 	(((__index) < 4) ? (HW_BEACON_BASE0 + (__index * 0x0200)) : \
+ 	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
+ 	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
+ 
++#define BEACON_BASE_TO_OFFSET(_base)	(((_base) - 0x4000) / 64)
++
+ /*
+  * BBP registers.
+  * The wordsize of the BBP is 8 bits.
+@@ -1975,6 +2094,10 @@ struct mac_iveiv_entry {
+ #define BBP109_TX0_POWER		FIELD8(0x0f)
+ #define BBP109_TX1_POWER		FIELD8(0xf0)
+ 
++/* BBP 110 */
++#define BBP110_TX2_POWER		FIELD8(0x0f)
++
++
+ /*
+  * BBP 138: Unknown
+  */
+@@ -2024,6 +2147,12 @@ struct mac_iveiv_entry {
+ #define RFCSR3_PA2_CASCODE_BIAS_CCKK	FIELD8(0x80)
+ /* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */
+ #define RFCSR3_VCOCAL_EN		FIELD8(0x80)
++/* Bits for RF3050 */
++#define RFCSR3_BIT1			FIELD8(0x02)
++#define RFCSR3_BIT2			FIELD8(0x04)
++#define RFCSR3_BIT3			FIELD8(0x08)
++#define RFCSR3_BIT4			FIELD8(0x10)
++#define RFCSR3_BIT5			FIELD8(0x20)
+ 
+ /*
+  * FRCSR 5:
+@@ -2036,6 +2165,8 @@ struct mac_iveiv_entry {
+ #define RFCSR6_R1			FIELD8(0x03)
+ #define RFCSR6_R2			FIELD8(0x40)
+ #define RFCSR6_TXDIV		FIELD8(0x0c)
++/* bits for RF3053 */
++#define RFCSR6_VCO_IC			FIELD8(0xc0)
+ 
+ /*
+  * RFCSR 7:
+@@ -2060,7 +2191,12 @@ struct mac_iveiv_entry {
+  * RFCSR 11:
+  */
+ #define RFCSR11_R			FIELD8(0x03)
++#define RFCSR11_PLL_MOD			FIELD8(0x0c)
+ #define RFCSR11_MOD			FIELD8(0xc0)
++/* bits for RF3053 */
++/* TODO: verify RFCSR11_MOD usage on other chips */
++#define RFCSR11_PLL_IDOH		FIELD8(0x40)
++
+ 
+ /*
+  * RFCSR 12:
+@@ -2092,6 +2228,10 @@ struct mac_iveiv_entry {
+ #define RFCSR17_R			FIELD8(0x20)
+ #define RFCSR17_CODE                   FIELD8(0x7f)
+ 
++/* RFCSR 18 */
++#define RFCSR18_XO_TUNE_BYPASS		FIELD8(0x40)
++
++
+ /*
+  * RFCSR 20:
+  */
+@@ -2152,6 +2292,12 @@ struct mac_iveiv_entry {
+ #define RFCSR31_RX_H20M			FIELD8(0x20)
+ #define RFCSR31_RX_CALIB		FIELD8(0x7f)
+ 
++/* RFCSR 32 bits for RF3053 */
++#define RFCSR32_TX_AGC_FC		FIELD8(0xf8)
++
++/* RFCSR 36 bits for RF3053 */
++#define RFCSR36_RF_BS			FIELD8(0x80)
++
+ /*
+  * RFCSR 38:
+  */
+@@ -2160,6 +2306,7 @@ struct mac_iveiv_entry {
+ /*
+  * RFCSR 39:
+  */
++#define RFCSR39_RX_DIV			FIELD8(0x40)
+ #define RFCSR39_RX_LO2_EN		FIELD8(0x80)
+ 
+ /*
+@@ -2167,12 +2314,36 @@ struct mac_iveiv_entry {
+  */
+ #define RFCSR49_TX			FIELD8(0x3f)
+ #define RFCSR49_EP			FIELD8(0xc0)
++/* bits for RT3593 */
++#define RFCSR49_TX_LO1_IC		FIELD8(0x1c)
++#define RFCSR49_TX_DIV			FIELD8(0x20)
+ 
+ /*
+  * RFCSR 50:
+  */
+ #define RFCSR50_TX			FIELD8(0x3f)
+ #define RFCSR50_EP			FIELD8(0xc0)
++/* bits for RT3593 */
++#define RFCSR50_TX_LO1_EN		FIELD8(0x20)
++#define RFCSR50_TX_LO2_EN		FIELD8(0x10)
++
++/* RFCSR 51 */
++/* bits for RT3593 */
++#define RFCSR51_BITS01			FIELD8(0x03)
++#define RFCSR51_BITS24			FIELD8(0x1c)
++#define RFCSR51_BITS57			FIELD8(0xe0)
++
++#define RFCSR53_TX_POWER		FIELD8(0x3f)
++#define RFCSR53_UNKNOWN			FIELD8(0xc0)
++
++#define RFCSR54_TX_POWER		FIELD8(0x3f)
++#define RFCSR54_UNKNOWN			FIELD8(0xc0)
++
++#define RFCSR55_TX_POWER		FIELD8(0x3f)
++#define RFCSR55_UNKNOWN			FIELD8(0xc0)
++
++#define RFCSR57_DRV_CC			FIELD8(0xfc)
++
+ 
+ /*
+  * RF registers
+@@ -2206,28 +2377,67 @@ struct mac_iveiv_entry {
+  * The wordsize of the EEPROM is 16 bits.
+  */
+ 
+-/*
+- * Chip ID
+- */
+-#define EEPROM_CHIP_ID			0x0000
++enum rt2800_eeprom_word {
++	EEPROM_CHIP_ID = 0,
++	EEPROM_VERSION,
++	EEPROM_MAC_ADDR_0,
++	EEPROM_MAC_ADDR_1,
++	EEPROM_MAC_ADDR_2,
++	EEPROM_NIC_CONF0,
++	EEPROM_NIC_CONF1,
++	EEPROM_FREQ,
++	EEPROM_LED_AG_CONF,
++	EEPROM_LED_ACT_CONF,
++	EEPROM_LED_POLARITY,
++	EEPROM_NIC_CONF2,
++	EEPROM_LNA,
++	EEPROM_RSSI_BG,
++	EEPROM_RSSI_BG2,
++	EEPROM_TXMIXER_GAIN_BG,
++	EEPROM_RSSI_A,
++	EEPROM_RSSI_A2,
++	EEPROM_TXMIXER_GAIN_A,
++	EEPROM_EIRP_MAX_TX_POWER,
++	EEPROM_TXPOWER_DELTA,
++	EEPROM_TXPOWER_BG1,
++	EEPROM_TXPOWER_BG2,
++	EEPROM_TSSI_BOUND_BG1,
++	EEPROM_TSSI_BOUND_BG2,
++	EEPROM_TSSI_BOUND_BG3,
++	EEPROM_TSSI_BOUND_BG4,
++	EEPROM_TSSI_BOUND_BG5,
++	EEPROM_TXPOWER_A1,
++	EEPROM_TXPOWER_A2,
++	EEPROM_TSSI_BOUND_A1,
++	EEPROM_TSSI_BOUND_A2,
++	EEPROM_TSSI_BOUND_A3,
++	EEPROM_TSSI_BOUND_A4,
++	EEPROM_TSSI_BOUND_A5,
++	EEPROM_TXPOWER_BYRATE,
++	EEPROM_BBP_START,
++
++	/* IDs for extended EEPROM format used by three-chain devices */
++	EEPROM_EXT_LNA2,
++	EEPROM_EXT_TXPOWER_BG3,
++	EEPROM_EXT_TXPOWER_A3,
++
++	/* New values must be added before this */
++	EEPROM_WORD_COUNT
++};
+ 
+ /*
+  * EEPROM Version
+  */
+-#define EEPROM_VERSION			0x0001
+ #define EEPROM_VERSION_FAE		FIELD16(0x00ff)
+ #define EEPROM_VERSION_VERSION		FIELD16(0xff00)
+ 
+ /*
+  * HW MAC address.
+  */
+-#define EEPROM_MAC_ADDR_0		0x0002
+ #define EEPROM_MAC_ADDR_BYTE0		FIELD16(0x00ff)
+ #define EEPROM_MAC_ADDR_BYTE1		FIELD16(0xff00)
+-#define EEPROM_MAC_ADDR_1		0x0003
+ #define EEPROM_MAC_ADDR_BYTE2		FIELD16(0x00ff)
+ #define EEPROM_MAC_ADDR_BYTE3		FIELD16(0xff00)
+-#define EEPROM_MAC_ADDR_2		0x0004
+ #define EEPROM_MAC_ADDR_BYTE4		FIELD16(0x00ff)
+ #define EEPROM_MAC_ADDR_BYTE5		FIELD16(0xff00)
+ 
+@@ -2237,7 +2447,6 @@ struct mac_iveiv_entry {
+  * TXPATH: 1: 1T, 2: 2T, 3: 3T
+  * RF_TYPE: RFIC type
+  */
+-#define	EEPROM_NIC_CONF0		0x001a
+ #define EEPROM_NIC_CONF0_RXPATH		FIELD16(0x000f)
+ #define EEPROM_NIC_CONF0_TXPATH		FIELD16(0x00f0)
+ #define EEPROM_NIC_CONF0_RF_TYPE		FIELD16(0x0f00)
+@@ -2261,7 +2470,6 @@ struct mac_iveiv_entry {
+  * BT_COEXIST: 0: disable, 1: enable
+  * DAC_TEST: 0: disable, 1: enable
+  */
+-#define	EEPROM_NIC_CONF1		0x001b
+ #define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
+ #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC		FIELD16(0x0002)
+ #define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G		FIELD16(0x0004)
+@@ -2281,7 +2489,6 @@ struct mac_iveiv_entry {
+ /*
+  * EEPROM frequency
+  */
+-#define	EEPROM_FREQ			0x001d
+ #define EEPROM_FREQ_OFFSET		FIELD16(0x00ff)
+ #define EEPROM_FREQ_LED_MODE		FIELD16(0x7f00)
+ #define EEPROM_FREQ_LED_POLARITY	FIELD16(0x1000)
+@@ -2298,9 +2505,6 @@ struct mac_iveiv_entry {
+  * POLARITY_GPIO_4: Polarity GPIO4 setting.
+  * LED_MODE: Led mode.
+  */
+-#define EEPROM_LED_AG_CONF		0x001e
+-#define EEPROM_LED_ACT_CONF		0x001f
+-#define EEPROM_LED_POLARITY		0x0020
+ #define EEPROM_LED_POLARITY_RDY_BG	FIELD16(0x0001)
+ #define EEPROM_LED_POLARITY_RDY_A	FIELD16(0x0002)
+ #define EEPROM_LED_POLARITY_ACT		FIELD16(0x0004)
+@@ -2317,7 +2521,6 @@ struct mac_iveiv_entry {
+  * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
+  * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
+  */
+-#define EEPROM_NIC_CONF2		0x0021
+ #define EEPROM_NIC_CONF2_RX_STREAM		FIELD16(0x000f)
+ #define EEPROM_NIC_CONF2_TX_STREAM		FIELD16(0x00f0)
+ #define EEPROM_NIC_CONF2_CRYSTAL		FIELD16(0x0600)
+@@ -2325,54 +2528,46 @@ struct mac_iveiv_entry {
+ /*
+  * EEPROM LNA
+  */
+-#define EEPROM_LNA			0x0022
+ #define EEPROM_LNA_BG			FIELD16(0x00ff)
+ #define EEPROM_LNA_A0			FIELD16(0xff00)
+ 
+ /*
+  * EEPROM RSSI BG offset
+  */
+-#define EEPROM_RSSI_BG			0x0023
+ #define EEPROM_RSSI_BG_OFFSET0		FIELD16(0x00ff)
+ #define EEPROM_RSSI_BG_OFFSET1		FIELD16(0xff00)
+ 
+ /*
+  * EEPROM RSSI BG2 offset
+  */
+-#define EEPROM_RSSI_BG2			0x0024
+ #define EEPROM_RSSI_BG2_OFFSET2		FIELD16(0x00ff)
+ #define EEPROM_RSSI_BG2_LNA_A1		FIELD16(0xff00)
+ 
+ /*
+  * EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2).
+  */
+-#define EEPROM_TXMIXER_GAIN_BG		0x0024
+ #define EEPROM_TXMIXER_GAIN_BG_VAL	FIELD16(0x0007)
+ 
+ /*
+  * EEPROM RSSI A offset
+  */
+-#define EEPROM_RSSI_A			0x0025
+ #define EEPROM_RSSI_A_OFFSET0		FIELD16(0x00ff)
+ #define EEPROM_RSSI_A_OFFSET1		FIELD16(0xff00)
+ 
+ /*
+  * EEPROM RSSI A2 offset
+  */
+-#define EEPROM_RSSI_A2			0x0026
+ #define EEPROM_RSSI_A2_OFFSET2		FIELD16(0x00ff)
+ #define EEPROM_RSSI_A2_LNA_A2		FIELD16(0xff00)
+ 
+ /*
+  * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2).
+  */
+-#define EEPROM_TXMIXER_GAIN_A		0x0026
+ #define EEPROM_TXMIXER_GAIN_A_VAL	FIELD16(0x0007)
+ 
+ /*
+  * EEPROM EIRP Maximum TX power values(unit: dbm)
+  */
+-#define EEPROM_EIRP_MAX_TX_POWER	0x0027
+ #define EEPROM_EIRP_MAX_TX_POWER_2GHZ	FIELD16(0x00ff)
+ #define EEPROM_EIRP_MAX_TX_POWER_5GHZ	FIELD16(0xff00)
+ 
+@@ -2383,7 +2578,6 @@ struct mac_iveiv_entry {
+  * TYPE: 1: Plus the delta value, 0: minus the delta value
+  * ENABLE: enable tx power compensation for 40BW
+  */
+-#define EEPROM_TXPOWER_DELTA		0x0028
+ #define EEPROM_TXPOWER_DELTA_VALUE_2G	FIELD16(0x003f)
+ #define EEPROM_TXPOWER_DELTA_TYPE_2G	FIELD16(0x0040)
+ #define EEPROM_TXPOWER_DELTA_ENABLE_2G	FIELD16(0x0080)
+@@ -2394,8 +2588,6 @@ struct mac_iveiv_entry {
+ /*
+  * EEPROM TXPOWER 802.11BG
+  */
+-#define	EEPROM_TXPOWER_BG1		0x0029
+-#define	EEPROM_TXPOWER_BG2		0x0030
+ #define EEPROM_TXPOWER_BG_SIZE		7
+ #define EEPROM_TXPOWER_BG_1		FIELD16(0x00ff)
+ #define EEPROM_TXPOWER_BG_2		FIELD16(0xff00)
+@@ -2407,7 +2599,6 @@ struct mac_iveiv_entry {
+  * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
+  *         reduced by (agc_step * -3)
+  */
+-#define EEPROM_TSSI_BOUND_BG1		0x0037
+ #define EEPROM_TSSI_BOUND_BG1_MINUS4	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_BG1_MINUS3	FIELD16(0xff00)
+ 
+@@ -2418,7 +2609,6 @@ struct mac_iveiv_entry {
+  * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
+  *         reduced by (agc_step * -1)
+  */
+-#define EEPROM_TSSI_BOUND_BG2		0x0038
+ #define EEPROM_TSSI_BOUND_BG2_MINUS2	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_BG2_MINUS1	FIELD16(0xff00)
+ 
+@@ -2428,7 +2618,6 @@ struct mac_iveiv_entry {
+  * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
+  *        increased by (agc_step * 1)
+  */
+-#define EEPROM_TSSI_BOUND_BG3		0x0039
+ #define EEPROM_TSSI_BOUND_BG3_REF	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_BG3_PLUS1	FIELD16(0xff00)
+ 
+@@ -2439,7 +2628,6 @@ struct mac_iveiv_entry {
+  * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
+  *        increased by (agc_step * 3)
+  */
+-#define EEPROM_TSSI_BOUND_BG4		0x003a
+ #define EEPROM_TSSI_BOUND_BG4_PLUS2	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_BG4_PLUS3	FIELD16(0xff00)
+ 
+@@ -2449,19 +2637,20 @@ struct mac_iveiv_entry {
+  *        increased by (agc_step * 4)
+  * AGC_STEP: Temperature compensation step.
+  */
+-#define EEPROM_TSSI_BOUND_BG5		0x003b
+ #define EEPROM_TSSI_BOUND_BG5_PLUS4	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_BG5_AGC_STEP	FIELD16(0xff00)
+ 
+ /*
+  * EEPROM TXPOWER 802.11A
+  */
+-#define EEPROM_TXPOWER_A1		0x003c
+-#define EEPROM_TXPOWER_A2		0x0053
+ #define EEPROM_TXPOWER_A_SIZE		6
+ #define EEPROM_TXPOWER_A_1		FIELD16(0x00ff)
+ #define EEPROM_TXPOWER_A_2		FIELD16(0xff00)
+ 
++/* EEPROM_TXPOWER_{A,G} fields for RT3593 */
++#define EEPROM_TXPOWER_ALC		FIELD8(0x1f)
++#define EEPROM_TXPOWER_FINE_CTRL	FIELD8(0xe0)
++
+ /*
+  * EEPROM temperature compensation boundaries 802.11A
+  * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
+@@ -2469,7 +2658,6 @@ struct mac_iveiv_entry {
+  * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
+  *         reduced by (agc_step * -3)
+  */
+-#define EEPROM_TSSI_BOUND_A1		0x006a
+ #define EEPROM_TSSI_BOUND_A1_MINUS4	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_A1_MINUS3	FIELD16(0xff00)
+ 
+@@ -2480,7 +2668,6 @@ struct mac_iveiv_entry {
+  * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
+  *         reduced by (agc_step * -1)
+  */
+-#define EEPROM_TSSI_BOUND_A2		0x006b
+ #define EEPROM_TSSI_BOUND_A2_MINUS2	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_A2_MINUS1	FIELD16(0xff00)
+ 
+@@ -2490,7 +2677,6 @@ struct mac_iveiv_entry {
+  * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
+  *        increased by (agc_step * 1)
+  */
+-#define EEPROM_TSSI_BOUND_A3		0x006c
+ #define EEPROM_TSSI_BOUND_A3_REF	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_A3_PLUS1	FIELD16(0xff00)
+ 
+@@ -2501,7 +2687,6 @@ struct mac_iveiv_entry {
+  * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
+  *        increased by (agc_step * 3)
+  */
+-#define EEPROM_TSSI_BOUND_A4		0x006d
+ #define EEPROM_TSSI_BOUND_A4_PLUS2	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_A4_PLUS3	FIELD16(0xff00)
+ 
+@@ -2511,14 +2696,12 @@ struct mac_iveiv_entry {
+  *        increased by (agc_step * 4)
+  * AGC_STEP: Temperature compensation step.
+  */
+-#define EEPROM_TSSI_BOUND_A5		0x006e
+ #define EEPROM_TSSI_BOUND_A5_PLUS4	FIELD16(0x00ff)
+ #define EEPROM_TSSI_BOUND_A5_AGC_STEP	FIELD16(0xff00)
+ 
+ /*
+  * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
+  */
+-#define EEPROM_TXPOWER_BYRATE		0x006f
+ #define EEPROM_TXPOWER_BYRATE_SIZE	9
+ 
+ #define EEPROM_TXPOWER_BYRATE_RATE0	FIELD16(0x000f)
+@@ -2529,11 +2712,14 @@ struct mac_iveiv_entry {
+ /*
+  * EEPROM BBP.
+  */
+-#define	EEPROM_BBP_START		0x0078
+ #define EEPROM_BBP_SIZE			16
+ #define EEPROM_BBP_VALUE		FIELD16(0x00ff)
+ #define EEPROM_BBP_REG_ID		FIELD16(0xff00)
+ 
++/* EEPROM_EXT_LNA2 */
++#define EEPROM_EXT_LNA2_A1		FIELD16(0x00ff)
++#define EEPROM_EXT_LNA2_A2		FIELD16(0xff00)
++
+ /*
+  * EEPROM IQ Calibration, unlike other entries those are byte addresses.
+  */
+@@ -2610,6 +2796,7 @@ struct mac_iveiv_entry {
+ #define MCU_RADAR			0x60
+ #define MCU_BOOT_SIGNAL			0x72
+ #define MCU_ANT_SELECT			0X73
++#define MCU_FREQ_OFFSET			0x74
+ #define MCU_BBP_SIGNAL			0x80
+ #define MCU_POWER_SAVE			0x83
+ #define MCU_BAND_SELECT		0x91
+@@ -2630,6 +2817,7 @@ struct mac_iveiv_entry {
+ #define TXWI_DESC_SIZE_5WORDS		(5 * sizeof(__le32))
+ 
+ #define RXWI_DESC_SIZE_4WORDS		(4 * sizeof(__le32))
++#define RXWI_DESC_SIZE_5WORDS		(5 * sizeof(__le32))
+ #define RXWI_DESC_SIZE_6WORDS		(6 * sizeof(__le32))
+ 
+ /*
+@@ -2750,18 +2938,15 @@ struct mac_iveiv_entry {
+ #define MAX_A_TXPOWER	15
+ #define DEFAULT_TXPOWER	5
+ 
++#define MIN_A_TXPOWER_3593	0
++#define MAX_A_TXPOWER_3593	31
++
+ #define TXPOWER_G_FROM_DEV(__txpower) \
+ 	((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+ 
+-#define TXPOWER_G_TO_DEV(__txpower) \
+-	clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
+-
+ #define TXPOWER_A_FROM_DEV(__txpower) \
+ 	((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+ 
+-#define TXPOWER_A_TO_DEV(__txpower) \
+-	clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
+-
+ /*
+  *  Board's maximun TX power limitation
+  */
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -221,6 +221,157 @@ static void rt2800_rf_write(struct rt2x0
+ 	mutex_unlock(&rt2x00dev->csr_mutex);
+ }
+ 
++static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
++	[EEPROM_CHIP_ID]		= 0x0000,
++	[EEPROM_VERSION]		= 0x0001,
++	[EEPROM_MAC_ADDR_0]		= 0x0002,
++	[EEPROM_MAC_ADDR_1]		= 0x0003,
++	[EEPROM_MAC_ADDR_2]		= 0x0004,
++	[EEPROM_NIC_CONF0]		= 0x001a,
++	[EEPROM_NIC_CONF1]		= 0x001b,
++	[EEPROM_FREQ]			= 0x001d,
++	[EEPROM_LED_AG_CONF]		= 0x001e,
++	[EEPROM_LED_ACT_CONF]		= 0x001f,
++	[EEPROM_LED_POLARITY]		= 0x0020,
++	[EEPROM_NIC_CONF2]		= 0x0021,
++	[EEPROM_LNA]			= 0x0022,
++	[EEPROM_RSSI_BG]		= 0x0023,
++	[EEPROM_RSSI_BG2]		= 0x0024,
++	[EEPROM_TXMIXER_GAIN_BG]	= 0x0024, /* overlaps with RSSI_BG2 */
++	[EEPROM_RSSI_A]			= 0x0025,
++	[EEPROM_RSSI_A2]		= 0x0026,
++	[EEPROM_TXMIXER_GAIN_A]		= 0x0026, /* overlaps with RSSI_A2 */
++	[EEPROM_EIRP_MAX_TX_POWER]	= 0x0027,
++	[EEPROM_TXPOWER_DELTA]		= 0x0028,
++	[EEPROM_TXPOWER_BG1]		= 0x0029,
++	[EEPROM_TXPOWER_BG2]		= 0x0030,
++	[EEPROM_TSSI_BOUND_BG1]		= 0x0037,
++	[EEPROM_TSSI_BOUND_BG2]		= 0x0038,
++	[EEPROM_TSSI_BOUND_BG3]		= 0x0039,
++	[EEPROM_TSSI_BOUND_BG4]		= 0x003a,
++	[EEPROM_TSSI_BOUND_BG5]		= 0x003b,
++	[EEPROM_TXPOWER_A1]		= 0x003c,
++	[EEPROM_TXPOWER_A2]		= 0x0053,
++	[EEPROM_TSSI_BOUND_A1]		= 0x006a,
++	[EEPROM_TSSI_BOUND_A2]		= 0x006b,
++	[EEPROM_TSSI_BOUND_A3]		= 0x006c,
++	[EEPROM_TSSI_BOUND_A4]		= 0x006d,
++	[EEPROM_TSSI_BOUND_A5]		= 0x006e,
++	[EEPROM_TXPOWER_BYRATE]		= 0x006f,
++	[EEPROM_BBP_START]		= 0x0078,
++};
++
++static const unsigned int rt2800_eeprom_map_ext[EEPROM_WORD_COUNT] = {
++	[EEPROM_CHIP_ID]		= 0x0000,
++	[EEPROM_VERSION]		= 0x0001,
++	[EEPROM_MAC_ADDR_0]		= 0x0002,
++	[EEPROM_MAC_ADDR_1]		= 0x0003,
++	[EEPROM_MAC_ADDR_2]		= 0x0004,
++	[EEPROM_NIC_CONF0]		= 0x001a,
++	[EEPROM_NIC_CONF1]		= 0x001b,
++	[EEPROM_NIC_CONF2]		= 0x001c,
++	[EEPROM_EIRP_MAX_TX_POWER]	= 0x0020,
++	[EEPROM_FREQ]			= 0x0022,
++	[EEPROM_LED_AG_CONF]		= 0x0023,
++	[EEPROM_LED_ACT_CONF]		= 0x0024,
++	[EEPROM_LED_POLARITY]		= 0x0025,
++	[EEPROM_LNA]			= 0x0026,
++	[EEPROM_EXT_LNA2]		= 0x0027,
++	[EEPROM_RSSI_BG]		= 0x0028,
++	[EEPROM_TXPOWER_DELTA]		= 0x0028, /* Overlaps with RSSI_BG */
++	[EEPROM_RSSI_BG2]		= 0x0029,
++	[EEPROM_TXMIXER_GAIN_BG]	= 0x0029, /* Overlaps with RSSI_BG2 */
++	[EEPROM_RSSI_A]			= 0x002a,
++	[EEPROM_RSSI_A2]		= 0x002b,
++	[EEPROM_TXMIXER_GAIN_A]		= 0x002b, /* Overlaps with RSSI_A2 */
++	[EEPROM_TXPOWER_BG1]		= 0x0030,
++	[EEPROM_TXPOWER_BG2]		= 0x0037,
++	[EEPROM_EXT_TXPOWER_BG3]	= 0x003e,
++	[EEPROM_TSSI_BOUND_BG1]		= 0x0045,
++	[EEPROM_TSSI_BOUND_BG2]		= 0x0046,
++	[EEPROM_TSSI_BOUND_BG3]		= 0x0047,
++	[EEPROM_TSSI_BOUND_BG4]		= 0x0048,
++	[EEPROM_TSSI_BOUND_BG5]		= 0x0049,
++	[EEPROM_TXPOWER_A1]		= 0x004b,
++	[EEPROM_TXPOWER_A2]		= 0x0065,
++	[EEPROM_EXT_TXPOWER_A3]		= 0x007f,
++	[EEPROM_TSSI_BOUND_A1]		= 0x009a,
++	[EEPROM_TSSI_BOUND_A2]		= 0x009b,
++	[EEPROM_TSSI_BOUND_A3]		= 0x009c,
++	[EEPROM_TSSI_BOUND_A4]		= 0x009d,
++	[EEPROM_TSSI_BOUND_A5]		= 0x009e,
++	[EEPROM_TXPOWER_BYRATE]		= 0x00a0,
++};
++
++static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
++					     const enum rt2800_eeprom_word word)
++{
++	const unsigned int *map;
++	unsigned int index;
++
++	if (WARN_ONCE(word >= EEPROM_WORD_COUNT,
++		      "%s: invalid EEPROM word %d\n",
++		      wiphy_name(rt2x00dev->hw->wiphy), word))
++		return 0;
++
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		map = rt2800_eeprom_map_ext;
++	else
++		map = rt2800_eeprom_map;
++
++	index = map[word];
++
++	/* Index 0 is valid only for EEPROM_CHIP_ID.
++	 * Otherwise it means that the offset of the
++	 * given word is not initialized in the map,
++	 * or that the field is not usable on the
++	 * actual chipset.
++	 */
++	WARN_ONCE(word != EEPROM_CHIP_ID && index == 0,
++		  "%s: invalid access of EEPROM word %d\n",
++		  wiphy_name(rt2x00dev->hw->wiphy), word);
++
++	return index;
++}
++
++static void *rt2800_eeprom_addr(struct rt2x00_dev *rt2x00dev,
++				const enum rt2800_eeprom_word word)
++{
++	unsigned int index;
++
++	index = rt2800_eeprom_word_index(rt2x00dev, word);
++	return rt2x00_eeprom_addr(rt2x00dev, index);
++}
++
++static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev,
++			       const enum rt2800_eeprom_word word, u16 *data)
++{
++	unsigned int index;
++
++	index = rt2800_eeprom_word_index(rt2x00dev, word);
++	rt2x00_eeprom_read(rt2x00dev, index, data);
++}
++
++static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
++				const enum rt2800_eeprom_word word, u16 data)
++{
++	unsigned int index;
++
++	index = rt2800_eeprom_word_index(rt2x00dev, word);
++	rt2x00_eeprom_write(rt2x00dev, index, data);
++}
++
++static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
++					  const enum rt2800_eeprom_word array,
++					  unsigned int offset,
++					  u16 *data)
++{
++	unsigned int index;
++
++	index = rt2800_eeprom_word_index(rt2x00dev, array);
++	rt2x00_eeprom_read(rt2x00dev, index + offset, data);
++}
++
+ static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
+ {
+ 	u32 reg;
+@@ -370,6 +521,29 @@ void rt2800_disable_wpdma(struct rt2x00_
+ }
+ EXPORT_SYMBOL_GPL(rt2800_disable_wpdma);
+ 
++void rt2800_get_txwi_rxwi_size(struct rt2x00_dev *rt2x00dev,
++			       unsigned short *txwi_size,
++			       unsigned short *rxwi_size)
++{
++	switch (rt2x00dev->chip.rt) {
++	case RT3593:
++		*txwi_size = TXWI_DESC_SIZE_4WORDS;
++		*rxwi_size = RXWI_DESC_SIZE_5WORDS;
++		break;
++
++	case RT5592:
++		*txwi_size = TXWI_DESC_SIZE_5WORDS;
++		*rxwi_size = RXWI_DESC_SIZE_6WORDS;
++		break;
++
++	default:
++		*txwi_size = TXWI_DESC_SIZE_4WORDS;
++		*rxwi_size = RXWI_DESC_SIZE_4WORDS;
++		break;
++	}
++}
++EXPORT_SYMBOL_GPL(rt2800_get_txwi_rxwi_size);
++
+ static bool rt2800_check_firmware_crc(const u8 *data, const size_t len)
+ {
+ 	u16 fw_crc;
+@@ -609,16 +783,16 @@ static int rt2800_agc_to_rssi(struct rt2
+ 	u8 offset2;
+ 
+ 	if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
+ 		offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0);
+ 		offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1);
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+ 		offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_OFFSET2);
+ 	} else {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
+ 		offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET0);
+ 		offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET1);
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+ 		offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_OFFSET2);
+ 	}
+ 
+@@ -766,6 +940,18 @@ void rt2800_txdone_entry(struct queue_en
+ }
+ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
+ 
++static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
++					  unsigned int index)
++{
++	return HW_BEACON_BASE(index);
++}
++
++static inline u8 rt2800_get_beacon_offset(struct rt2x00_dev *rt2x00dev,
++					  unsigned int index)
++{
++	return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
++}
++
+ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
+ {
+ 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+@@ -818,7 +1004,8 @@ void rt2800_write_beacon(struct queue_en
+ 		return;
+ 	}
+ 
+-	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
++	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
++
+ 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+ 				   entry->skb->len + padding_len);
+ 
+@@ -837,10 +1024,13 @@ void rt2800_write_beacon(struct queue_en
+ EXPORT_SYMBOL_GPL(rt2800_write_beacon);
+ 
+ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
+-						unsigned int beacon_base)
++						unsigned int index)
+ {
+ 	int i;
+ 	const int txwi_desc_size = rt2x00dev->bcn->winfo_size;
++	unsigned int beacon_base;
++
++	beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
+ 
+ 	/*
+ 	 * For the Beacon base registers we only need to clear
+@@ -867,8 +1057,7 @@ void rt2800_clear_beacon(struct queue_en
+ 	/*
+ 	 * Clear beacon.
+ 	 */
+-	rt2800_clear_beacon_register(rt2x00dev,
+-				     HW_BEACON_OFFSET(entry->entry_idx));
++	rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
+ 
+ 	/*
+ 	 * Enabled beaconing again.
+@@ -890,6 +1079,9 @@ const struct rt2x00debug rt2800_rt2x00de
+ 		.word_count	= CSR_REG_SIZE / sizeof(u32),
+ 	},
+ 	.eeprom	= {
++		/* NOTE: The local EEPROM access functions can't
++		 * be used here, use the generic versions instead.
++		 */
+ 		.read		= rt2x00_eeprom_read,
+ 		.write		= rt2x00_eeprom_write,
+ 		.word_base	= EEPROM_BASE,
+@@ -1547,7 +1739,7 @@ static void rt2800_config_3572bt_ant(str
+ 	led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
+ 	if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
+ 	    led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ 		led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
+ 		if (led_ctrl == 0 || led_ctrl > 0x40) {
+ 			rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, led_g_mode);
+@@ -1609,7 +1801,7 @@ void rt2800_config_ant(struct rt2x00_dev
+ 			rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+ 		break;
+ 	case 3:
+-		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
++		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+ 		break;
+ 	}
+ 
+@@ -1622,7 +1814,7 @@ void rt2800_config_ant(struct rt2x00_dev
+ 		    rt2x00_rt(rt2x00dev, RT3090) ||
+ 		    rt2x00_rt(rt2x00dev, RT3352) ||
+ 		    rt2x00_rt(rt2x00dev, RT3390)) {
+-			rt2x00_eeprom_read(rt2x00dev,
++			rt2800_eeprom_read(rt2x00dev,
+ 					   EEPROM_NIC_CONF1, &eeprom);
+ 			if (rt2x00_get_field16(eeprom,
+ 						EEPROM_NIC_CONF1_ANT_DIVERSITY))
+@@ -1649,6 +1841,13 @@ void rt2800_config_ant(struct rt2x00_dev
+ 
+ 	rt2800_bbp_write(rt2x00dev, 3, r3);
+ 	rt2800_bbp_write(rt2x00dev, 1, r1);
++
++	if (rt2x00_rt(rt2x00dev, RT3593)) {
++		if (ant->rx_chain_num == 1)
++			rt2800_bbp_write(rt2x00dev, 86, 0x00);
++		else
++			rt2800_bbp_write(rt2x00dev, 86, 0x46);
++	}
+ }
+ EXPORT_SYMBOL_GPL(rt2800_config_ant);
+ 
+@@ -1659,22 +1858,73 @@ static void rt2800_config_lna_gain(struc
+ 	short lna_gain;
+ 
+ 	if (libconf->rf.channel <= 14) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ 		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
+ 	} else if (libconf->rf.channel <= 64) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ 		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
+ 	} else if (libconf->rf.channel <= 128) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+-		lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
++		if (rt2x00_rt(rt2x00dev, RT3593)) {
++			rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
++			lna_gain = rt2x00_get_field16(eeprom,
++						      EEPROM_EXT_LNA2_A1);
++		} else {
++			rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
++			lna_gain = rt2x00_get_field16(eeprom,
++						      EEPROM_RSSI_BG2_LNA_A1);
++		}
+ 	} else {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+-		lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
++		if (rt2x00_rt(rt2x00dev, RT3593)) {
++			rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
++			lna_gain = rt2x00_get_field16(eeprom,
++						      EEPROM_EXT_LNA2_A2);
++		} else {
++			rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
++			lna_gain = rt2x00_get_field16(eeprom,
++						      EEPROM_RSSI_A2_LNA_A2);
++		}
+ 	}
+ 
+ 	rt2x00dev->lna_gain = lna_gain;
+ }
+ 
++#define FREQ_OFFSET_BOUND	0x5f
++
++static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
++{
++	u8 freq_offset, prev_freq_offset;
++	u8 rfcsr, prev_rfcsr;
++
++	freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
++	freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
++
++	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
++	prev_rfcsr = rfcsr;
++
++	rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
++	if (rfcsr == prev_rfcsr)
++		return;
++
++	if (rt2x00_is_usb(rt2x00dev)) {
++		rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
++				   freq_offset, prev_rfcsr);
++		return;
++	}
++
++	prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
++	while (prev_freq_offset != freq_offset) {
++		if (prev_freq_offset < freq_offset)
++			prev_freq_offset++;
++		else
++			prev_freq_offset--;
++
++		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
++		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
++
++		usleep_range(1000, 1500);
++	}
++}
++
+ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
+ 					 struct ieee80211_conf *conf,
+ 					 struct rf_channel *rf,
+@@ -1993,22 +2243,306 @@ static void rt2800_config_channel_rf3052
+ 	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+ }
+ 
+-#define POWER_BOUND		0x27
+-#define POWER_BOUND_5G		0x2b
+-#define FREQ_OFFSET_BOUND	0x5f
+-
+-static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
++static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
++					 struct ieee80211_conf *conf,
++					 struct rf_channel *rf,
++					 struct channel_info *info)
+ {
++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++	u8 txrx_agc_fc;
++	u8 txrx_h20m;
+ 	u8 rfcsr;
++	u8 bbp;
++	const bool txbf_enabled = false; /* TODO */
+ 
+-	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+-	if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
+-		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
++	/* TODO: use TX{0,1,2}FinePowerControl values from EEPROM */
++	rt2800_bbp_read(rt2x00dev, 109, &bbp);
++	rt2x00_set_field8(&bbp, BBP109_TX0_POWER, 0);
++	rt2x00_set_field8(&bbp, BBP109_TX1_POWER, 0);
++	rt2800_bbp_write(rt2x00dev, 109, bbp);
++
++	rt2800_bbp_read(rt2x00dev, 110, &bbp);
++	rt2x00_set_field8(&bbp, BBP110_TX2_POWER, 0);
++	rt2800_bbp_write(rt2x00dev, 110, bbp);
++
++	if (rf->channel <= 14) {
++		/* Restore BBP 25 & 26 for 2.4 GHz */
++		rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25);
++		rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26);
++	} else {
++		/* Hard code BBP 25 & 26 for 5GHz */
++
++		/* Enable IQ Phase correction */
++		rt2800_bbp_write(rt2x00dev, 25, 0x09);
++		/* Setup IQ Phase correction value */
++		rt2800_bbp_write(rt2x00dev, 26, 0xff);
++	}
++
++	rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
++	rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3 & 0xf);
++
++	rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR11_R, (rf->rf2 & 0x3));
++	rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR11_PLL_IDOH, 1);
++	if (rf->channel <= 14)
++		rt2x00_set_field8(&rfcsr, RFCSR11_PLL_MOD, 1);
+ 	else
+-		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
+-	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
++		rt2x00_set_field8(&rfcsr, RFCSR11_PLL_MOD, 2);
++	rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 53, &rfcsr);
++	if (rf->channel <= 14) {
++		rfcsr = 0;
++		rt2x00_set_field8(&rfcsr, RFCSR53_TX_POWER,
++				  info->default_power1 & 0x1f);
++	} else {
++		if (rt2x00_is_usb(rt2x00dev))
++			rfcsr = 0x40;
++
++		rt2x00_set_field8(&rfcsr, RFCSR53_TX_POWER,
++				  ((info->default_power1 & 0x18) << 1) |
++				  (info->default_power1 & 7));
++	}
++	rt2800_rfcsr_write(rt2x00dev, 53, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 55, &rfcsr);
++	if (rf->channel <= 14) {
++		rfcsr = 0;
++		rt2x00_set_field8(&rfcsr, RFCSR55_TX_POWER,
++				  info->default_power2 & 0x1f);
++	} else {
++		if (rt2x00_is_usb(rt2x00dev))
++			rfcsr = 0x40;
++
++		rt2x00_set_field8(&rfcsr, RFCSR55_TX_POWER,
++				  ((info->default_power2 & 0x18) << 1) |
++				  (info->default_power2 & 7));
++	}
++	rt2800_rfcsr_write(rt2x00dev, 55, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 54, &rfcsr);
++	if (rf->channel <= 14) {
++		rfcsr = 0;
++		rt2x00_set_field8(&rfcsr, RFCSR54_TX_POWER,
++				  info->default_power3 & 0x1f);
++	} else {
++		if (rt2x00_is_usb(rt2x00dev))
++			rfcsr = 0x40;
++
++		rt2x00_set_field8(&rfcsr, RFCSR54_TX_POWER,
++				  ((info->default_power3 & 0x18) << 1) |
++				  (info->default_power3 & 7));
++	}
++	rt2800_rfcsr_write(rt2x00dev, 54, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
++	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
++	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
++	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
++	rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
++	rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
++	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
++	rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
++
++	switch (rt2x00dev->default_ant.tx_chain_num) {
++	case 3:
++		rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
++		/* fallthrough */
++	case 2:
++		rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
++		/* fallthrough */
++	case 1:
++		rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
++		break;
++	}
++
++	switch (rt2x00dev->default_ant.rx_chain_num) {
++	case 3:
++		rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
++		/* fallthrough */
++	case 2:
++		rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
++		/* fallthrough */
++	case 1:
++		rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
++		break;
++	}
++	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
++
++	rt2800_adjust_freq_offset(rt2x00dev);
++
++	if (conf_is_ht40(conf)) {
++		txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
++						RFCSR24_TX_AGC_FC);
++		txrx_h20m = rt2x00_get_field8(drv_data->calibration_bw40,
++					      RFCSR24_TX_H20M);
++	} else {
++		txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20,
++						RFCSR24_TX_AGC_FC);
++		txrx_h20m = rt2x00_get_field8(drv_data->calibration_bw20,
++					      RFCSR24_TX_H20M);
++	}
++
++	/* NOTE: the reference driver does not writes the new value
++	 * back to RFCSR 32
++	 */
++	rt2800_rfcsr_read(rt2x00dev, 32, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR32_TX_AGC_FC, txrx_agc_fc);
++
++	if (rf->channel <= 14)
++		rfcsr = 0xa0;
++	else
++		rfcsr = 0x80;
++	rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, txrx_h20m);
++	rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, txrx_h20m);
++	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
++
++	/* Band selection */
++	rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr);
++	if (rf->channel <= 14)
++		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
++	else
++		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
++	rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 34, &rfcsr);
++	if (rf->channel <= 14)
++		rfcsr = 0x3c;
++	else
++		rfcsr = 0x20;
++	rt2800_rfcsr_write(rt2x00dev, 34, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
++	if (rf->channel <= 14)
++		rfcsr = 0x1a;
++	else
++		rfcsr = 0x12;
++	rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
++	if (rf->channel >= 1 && rf->channel <= 14)
++		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
++	else if (rf->channel >= 36 && rf->channel <= 64)
++		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
++	else if (rf->channel >= 100 && rf->channel <= 128)
++		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
++	else
++		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
++	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
++	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
++
++	rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
++
++	if (rf->channel <= 14) {
++		rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
++		rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
++	} else {
++		rt2800_rfcsr_write(rt2x00dev, 10, 0xd8);
++		rt2800_rfcsr_write(rt2x00dev, 13, 0x23);
++	}
++
++	rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR51_BITS01, 1);
++	rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
++	if (rf->channel <= 14) {
++		rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, 5);
++		rt2x00_set_field8(&rfcsr, RFCSR51_BITS57, 3);
++	} else {
++		rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, 4);
++		rt2x00_set_field8(&rfcsr, RFCSR51_BITS57, 2);
++	}
++	rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
++	if (rf->channel <= 14)
++		rt2x00_set_field8(&rfcsr, RFCSR49_TX_LO1_IC, 3);
++	else
++		rt2x00_set_field8(&rfcsr, RFCSR49_TX_LO1_IC, 2);
++
++	if (txbf_enabled)
++		rt2x00_set_field8(&rfcsr, RFCSR49_TX_DIV, 1);
++
++	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR50_TX_LO1_EN, 0);
++	rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr);
++	if (rf->channel <= 14)
++		rt2x00_set_field8(&rfcsr, RFCSR57_DRV_CC, 0x1b);
++	else
++		rt2x00_set_field8(&rfcsr, RFCSR57_DRV_CC, 0x0f);
++	rt2800_rfcsr_write(rt2x00dev, 57, rfcsr);
++
++	if (rf->channel <= 14) {
++		rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
++		rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
++	} else {
++		rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
++		rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
++	}
++
++	/* Initiate VCO calibration */
++	rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
++	if (rf->channel <= 14) {
++		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
++	} else {
++		rt2x00_set_field8(&rfcsr, RFCSR3_BIT1, 1);
++		rt2x00_set_field8(&rfcsr, RFCSR3_BIT2, 1);
++		rt2x00_set_field8(&rfcsr, RFCSR3_BIT3, 1);
++		rt2x00_set_field8(&rfcsr, RFCSR3_BIT4, 1);
++		rt2x00_set_field8(&rfcsr, RFCSR3_BIT5, 1);
++		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
++	}
++	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
++
++	if (rf->channel >= 1 && rf->channel <= 14) {
++		rfcsr = 0x23;
++		if (txbf_enabled)
++			rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
++		rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
++
++		rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
++	} else if (rf->channel >= 36 && rf->channel <= 64) {
++		rfcsr = 0x36;
++		if (txbf_enabled)
++			rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
++		rt2800_rfcsr_write(rt2x00dev, 39, 0x36);
++
++		rt2800_rfcsr_write(rt2x00dev, 45, 0xeb);
++	} else if (rf->channel >= 100 && rf->channel <= 128) {
++		rfcsr = 0x32;
++		if (txbf_enabled)
++			rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
++		rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
++
++		rt2800_rfcsr_write(rt2x00dev, 45, 0xb3);
++	} else {
++		rfcsr = 0x30;
++		if (txbf_enabled)
++			rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
++		rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
++
++		rt2800_rfcsr_write(rt2x00dev, 45, 0x9b);
++	}
+ }
+ 
++#define POWER_BOUND		0x27
++#define POWER_BOUND_5G		0x2b
++
+ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
+ 					 struct ieee80211_conf *conf,
+ 					 struct rf_channel *rf,
+@@ -2563,6 +3097,23 @@ static void rt2800_iq_calibrate(struct r
+ 	rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0);
+ }
+ 
++static char rt2800_txpower_to_dev(struct rt2x00_dev *rt2x00dev,
++				  unsigned int channel,
++				  char txpower)
++{
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
++
++	if (channel <= 14)
++		return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
++
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
++			       MAX_A_TXPOWER_3593);
++	else
++		return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
++}
++
+ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ 				  struct ieee80211_conf *conf,
+ 				  struct rf_channel *rf,
+@@ -2572,13 +3123,14 @@ static void rt2800_config_channel(struct
+ 	unsigned int tx_pin;
+ 	u8 bbp, rfcsr;
+ 
+-	if (rf->channel <= 14) {
+-		info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
+-		info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2);
+-	} else {
+-		info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1);
+-		info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2);
+-	}
++	info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
++						     info->default_power1);
++	info->default_power2 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
++						     info->default_power2);
++	if (rt2x00dev->default_ant.tx_chain_num > 2)
++		info->default_power3 =
++			rt2800_txpower_to_dev(rt2x00dev, rf->channel,
++					      info->default_power3);
+ 
+ 	switch (rt2x00dev->chip.rf) {
+ 	case RF2020:
+@@ -2591,6 +3143,9 @@ static void rt2800_config_channel(struct
+ 	case RF3052:
+ 		rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
+ 		break;
++	case RF3053:
++		rt2800_config_channel_rf3053(rt2x00dev, conf, rf, info);
++		break;
+ 	case RF3290:
+ 		rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
+ 		break;
+@@ -2636,6 +3191,23 @@ static void rt2800_config_channel(struct
+ 		rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
+ 		rt2800_bbp_write(rt2x00dev, 27, 0x20);
+ 		rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
++	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
++		if (rf->channel > 14) {
++			/* Disable CCK Packet detection on 5GHz */
++			rt2800_bbp_write(rt2x00dev, 70, 0x00);
++		} else {
++			rt2800_bbp_write(rt2x00dev, 70, 0x0a);
++		}
++
++		if (conf_is_ht40(conf))
++			rt2800_bbp_write(rt2x00dev, 105, 0x04);
++		else
++			rt2800_bbp_write(rt2x00dev, 105, 0x34);
++
++		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
++		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
++		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
++		rt2800_bbp_write(rt2x00dev, 77, 0x98);
+ 	} else {
+ 		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+@@ -2651,16 +3223,27 @@ static void rt2800_config_channel(struct
+ 				rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ 				rt2800_bbp_write(rt2x00dev, 75, 0x46);
+ 			} else {
+-				rt2800_bbp_write(rt2x00dev, 82, 0x84);
++				if (rt2x00_rt(rt2x00dev, RT3593))
++					rt2800_bbp_write(rt2x00dev, 82, 0x62);
++				else
++					rt2800_bbp_write(rt2x00dev, 82, 0x84);
+ 				rt2800_bbp_write(rt2x00dev, 75, 0x50);
+ 			}
++			if (rt2x00_rt(rt2x00dev, RT3593))
++				rt2800_bbp_write(rt2x00dev, 83, 0x8a);
+ 		}
++
+ 	} else {
+ 		if (rt2x00_rt(rt2x00dev, RT3572))
+ 			rt2800_bbp_write(rt2x00dev, 82, 0x94);
++		else if (rt2x00_rt(rt2x00dev, RT3593))
++			rt2800_bbp_write(rt2x00dev, 82, 0x82);
+ 		else
+ 			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+ 
++		if (rt2x00_rt(rt2x00dev, RT3593))
++			rt2800_bbp_write(rt2x00dev, 83, 0x9a);
++
+ 		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
+ 			rt2800_bbp_write(rt2x00dev, 75, 0x46);
+ 		else
+@@ -2731,6 +3314,41 @@ static void rt2800_config_channel(struct
+ 	if (rt2x00_rt(rt2x00dev, RT3572))
+ 		rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
+ 
++	if (rt2x00_rt(rt2x00dev, RT3593)) {
++		if (rt2x00_is_usb(rt2x00dev)) {
++			rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
++
++			/* Band selection. GPIO #8 controls all paths */
++			rt2x00_set_field32(&reg, GPIO_CTRL_DIR8, 0);
++			if (rf->channel <= 14)
++				rt2x00_set_field32(&reg, GPIO_CTRL_VAL8, 1);
++			else
++				rt2x00_set_field32(&reg, GPIO_CTRL_VAL8, 0);
++
++			rt2x00_set_field32(&reg, GPIO_CTRL_DIR4, 0);
++			rt2x00_set_field32(&reg, GPIO_CTRL_DIR7, 0);
++
++			/* LNA PE control.
++			* GPIO #4 controls PE0 and PE1,
++			* GPIO #7 controls PE2
++			*/
++			rt2x00_set_field32(&reg, GPIO_CTRL_VAL4, 1);
++			rt2x00_set_field32(&reg, GPIO_CTRL_VAL7, 1);
++
++			rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
++		}
++
++		/* AGC init */
++		if (rf->channel <= 14)
++			reg = 0x1c + 2 * rt2x00dev->lna_gain;
++		else
++			reg = 0x22 + ((rt2x00dev->lna_gain * 5) / 3);
++
++		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
++
++		usleep_range(1000, 1500);
++	}
++
+ 	if (rt2x00_rt(rt2x00dev, RT5592)) {
+ 		rt2800_bbp_write(rt2x00dev, 195, 141);
+ 		rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
+@@ -2790,6 +3408,13 @@ static int rt2800_get_gain_calibration_d
+ 	int i;
+ 
+ 	/*
++	 * First check if temperature compensation is supported.
++	 */
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++	if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC))
++		return 0;
++
++	/*
+ 	 * Read TSSI boundaries for temperature compensation from
+ 	 * the EEPROM.
+ 	 *
+@@ -2798,62 +3423,62 @@ static int rt2800_get_gain_calibration_d
+ 	 * Example TSSI bounds  0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
+ 	 */
+ 	if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
+ 		tssi_bounds[0] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG1_MINUS4);
+ 		tssi_bounds[1] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG1_MINUS3);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
+ 		tssi_bounds[2] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG2_MINUS2);
+ 		tssi_bounds[3] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG2_MINUS1);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
+ 		tssi_bounds[4] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG3_REF);
+ 		tssi_bounds[5] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG3_PLUS1);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
+ 		tssi_bounds[6] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG4_PLUS2);
+ 		tssi_bounds[7] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG4_PLUS3);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
+ 		tssi_bounds[8] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_BG5_PLUS4);
+ 
+ 		step = rt2x00_get_field16(eeprom,
+ 					  EEPROM_TSSI_BOUND_BG5_AGC_STEP);
+ 	} else {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
+ 		tssi_bounds[0] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A1_MINUS4);
+ 		tssi_bounds[1] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A1_MINUS3);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
+ 		tssi_bounds[2] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A2_MINUS2);
+ 		tssi_bounds[3] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A2_MINUS1);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
+ 		tssi_bounds[4] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A3_REF);
+ 		tssi_bounds[5] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A3_PLUS1);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
+ 		tssi_bounds[6] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A4_PLUS2);
+ 		tssi_bounds[7] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A4_PLUS3);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
+ 		tssi_bounds[8] = rt2x00_get_field16(eeprom,
+ 					EEPROM_TSSI_BOUND_A5_PLUS4);
+ 
+@@ -2899,7 +3524,7 @@ static int rt2800_get_txpower_bw_comp(st
+ 	u8 comp_type;
+ 	int comp_value = 0;
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
+ 
+ 	/*
+ 	 * HT40 compensation not required.
+@@ -2966,6 +3591,9 @@ static u8 rt2800_compensate_txpower(stru
+ 	u8 eirp_txpower_criterion;
+ 	u8 reg_limit;
+ 
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		return min_t(u8, txpower, 0xc);
++
+ 	if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
+ 		/*
+ 		 * Check if eirp txpower exceed txpower_limit.
+@@ -2974,12 +3602,12 @@ static u8 rt2800_compensate_txpower(stru
+ 		 * .11b data rate need add additional 4dbm
+ 		 * when calculating eirp txpower.
+ 		 */
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
+-				   &eeprom);
++		rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++					      1, &eeprom);
+ 		criterion = rt2x00_get_field16(eeprom,
+ 					       EEPROM_TXPOWER_BYRATE_RATE0);
+ 
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
++		rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
+ 				   &eeprom);
+ 
+ 		if (band == IEEE80211_BAND_2GHZ)
+@@ -3001,6 +3629,412 @@ static u8 rt2800_compensate_txpower(stru
+ 	return min_t(u8, txpower, 0xc);
+ }
+ 
++
++enum {
++	TX_PWR_CFG_0_IDX,
++	TX_PWR_CFG_1_IDX,
++	TX_PWR_CFG_2_IDX,
++	TX_PWR_CFG_3_IDX,
++	TX_PWR_CFG_4_IDX,
++	TX_PWR_CFG_5_IDX,
++	TX_PWR_CFG_6_IDX,
++	TX_PWR_CFG_7_IDX,
++	TX_PWR_CFG_8_IDX,
++	TX_PWR_CFG_9_IDX,
++	TX_PWR_CFG_0_EXT_IDX,
++	TX_PWR_CFG_1_EXT_IDX,
++	TX_PWR_CFG_2_EXT_IDX,
++	TX_PWR_CFG_3_EXT_IDX,
++	TX_PWR_CFG_4_EXT_IDX,
++	TX_PWR_CFG_IDX_COUNT,
++};
++
++static void rt2800_config_txpower_rt3593(struct rt2x00_dev *rt2x00dev,
++					 struct ieee80211_channel *chan,
++					 int power_level)
++{
++	u8 txpower;
++	u16 eeprom;
++	u32 regs[TX_PWR_CFG_IDX_COUNT];
++	unsigned int offset;
++	enum ieee80211_band band = chan->band;
++	int delta;
++	int i;
++
++	memset(regs, '\0', sizeof(regs));
++
++	/* TODO: adapt TX power reduction from the rt28xx code */
++
++	/* calculate temperature compensation delta */
++	delta = rt2800_get_gain_calibration_delta(rt2x00dev);
++
++	if (band == IEEE80211_BAND_5GHZ)
++		offset = 16;
++	else
++		offset = 0;
++
++	if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
++		offset += 8;
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset, &eeprom);
++
++	/* CCK 1MBS,2MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 1, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_CCK1_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_CCK1_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
++			   TX_PWR_CFG_0_EXT_CCK1_CH2, txpower);
++
++	/* CCK 5.5MBS,11MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 1, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_CCK5_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_CCK5_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
++			   TX_PWR_CFG_0_EXT_CCK5_CH2, txpower);
++
++	/* OFDM 6MBS,9MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_OFDM6_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_OFDM6_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
++			   TX_PWR_CFG_0_EXT_OFDM6_CH2, txpower);
++
++	/* OFDM 12MBS,18MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_OFDM12_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
++			   TX_PWR_CFG_0_OFDM12_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
++			   TX_PWR_CFG_0_EXT_OFDM12_CH2, txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 1, &eeprom);
++
++	/* OFDM 24MBS,36MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_OFDM24_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_OFDM24_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
++			   TX_PWR_CFG_1_EXT_OFDM24_CH2, txpower);
++
++	/* OFDM 48MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_OFDM48_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_OFDM48_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
++			   TX_PWR_CFG_1_EXT_OFDM48_CH2, txpower);
++
++	/* OFDM 54MBS */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
++			   TX_PWR_CFG_7_OFDM54_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
++			   TX_PWR_CFG_7_OFDM54_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
++			   TX_PWR_CFG_7_OFDM54_CH2, txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 2, &eeprom);
++
++	/* MCS 0,1 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_MCS0_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_MCS0_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
++			   TX_PWR_CFG_1_EXT_MCS0_CH2, txpower);
++
++	/* MCS 2,3 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_MCS2_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
++			   TX_PWR_CFG_1_MCS2_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
++			   TX_PWR_CFG_1_EXT_MCS2_CH2, txpower);
++
++	/* MCS 4,5 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS4_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS4_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
++			   TX_PWR_CFG_2_EXT_MCS4_CH2, txpower);
++
++	/* MCS 6 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS6_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS6_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
++			   TX_PWR_CFG_2_EXT_MCS6_CH2, txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 3, &eeprom);
++
++	/* MCS 7 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
++			   TX_PWR_CFG_7_MCS7_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
++			   TX_PWR_CFG_7_MCS7_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
++			   TX_PWR_CFG_7_MCS7_CH2, txpower);
++
++	/* MCS 8,9 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS8_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS8_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
++			   TX_PWR_CFG_2_EXT_MCS8_CH2, txpower);
++
++	/* MCS 10,11 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS10_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
++			   TX_PWR_CFG_2_MCS10_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
++			   TX_PWR_CFG_2_EXT_MCS10_CH2, txpower);
++
++	/* MCS 12,13 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_MCS12_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_MCS12_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
++			   TX_PWR_CFG_3_EXT_MCS12_CH2, txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 4, &eeprom);
++
++	/* MCS 14 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_MCS14_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_MCS14_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
++			   TX_PWR_CFG_3_EXT_MCS14_CH2, txpower);
++
++	/* MCS 15 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
++			   TX_PWR_CFG_8_MCS15_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
++			   TX_PWR_CFG_8_MCS15_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
++			   TX_PWR_CFG_8_MCS15_CH2, txpower);
++
++	/* MCS 16,17 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
++			   TX_PWR_CFG_5_MCS16_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
++			   TX_PWR_CFG_5_MCS16_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
++			   TX_PWR_CFG_5_MCS16_CH2, txpower);
++
++	/* MCS 18,19 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
++			   TX_PWR_CFG_5_MCS18_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
++			   TX_PWR_CFG_5_MCS18_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
++			   TX_PWR_CFG_5_MCS18_CH2, txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 5, &eeprom);
++
++	/* MCS 20,21 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
++			   TX_PWR_CFG_6_MCS20_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
++			   TX_PWR_CFG_6_MCS20_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
++			   TX_PWR_CFG_6_MCS20_CH2, txpower);
++
++	/* MCS 22 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
++			   TX_PWR_CFG_6_MCS22_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
++			   TX_PWR_CFG_6_MCS22_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
++			   TX_PWR_CFG_6_MCS22_CH2, txpower);
++
++	/* MCS 23 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
++			   TX_PWR_CFG_8_MCS23_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
++			   TX_PWR_CFG_8_MCS23_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
++			   TX_PWR_CFG_8_MCS23_CH2, txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 6, &eeprom);
++
++	/* STBC, MCS 0,1 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_STBC0_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_STBC0_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
++			   TX_PWR_CFG_3_EXT_STBC0_CH2, txpower);
++
++	/* STBC, MCS 2,3 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_STBC2_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
++			   TX_PWR_CFG_3_STBC2_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
++			   TX_PWR_CFG_3_EXT_STBC2_CH2, txpower);
++
++	/* STBC, MCS 4,5 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_4_EXT_IDX], TX_PWR_CFG_RATE0,
++			   txpower);
++
++	/* STBC, MCS 6 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE2, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE3, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_4_EXT_IDX], TX_PWR_CFG_RATE2,
++			   txpower);
++
++	/* read the next four txpower values */
++	rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++				      offset + 7, &eeprom);
++
++	/* STBC, MCS 7 */
++	txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
++	txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
++					    txpower, delta);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
++			   TX_PWR_CFG_9_STBC7_CH0, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
++			   TX_PWR_CFG_9_STBC7_CH1, txpower);
++	rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
++			   TX_PWR_CFG_9_STBC7_CH2, txpower);
++
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, regs[TX_PWR_CFG_0_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, regs[TX_PWR_CFG_1_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, regs[TX_PWR_CFG_2_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, regs[TX_PWR_CFG_3_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, regs[TX_PWR_CFG_4_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_5, regs[TX_PWR_CFG_5_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_6, regs[TX_PWR_CFG_6_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, regs[TX_PWR_CFG_7_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, regs[TX_PWR_CFG_8_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, regs[TX_PWR_CFG_9_IDX]);
++
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_0_EXT,
++			      regs[TX_PWR_CFG_0_EXT_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_1_EXT,
++			      regs[TX_PWR_CFG_1_EXT_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_2_EXT,
++			      regs[TX_PWR_CFG_2_EXT_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_3_EXT,
++			      regs[TX_PWR_CFG_3_EXT_IDX]);
++	rt2800_register_write(rt2x00dev, TX_PWR_CFG_4_EXT,
++			      regs[TX_PWR_CFG_4_EXT_IDX]);
++
++	for (i = 0; i < TX_PWR_CFG_IDX_COUNT; i++)
++		rt2x00_dbg(rt2x00dev,
++			   "band:%cGHz, BW:%c0MHz, TX_PWR_CFG_%d%s = %08lx\n",
++			   (band == IEEE80211_BAND_5GHZ) ? '5' : '2',
++			   (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) ?
++								'4' : '2',
++			   (i > TX_PWR_CFG_9_IDX) ?
++					(i - TX_PWR_CFG_9_IDX - 1) : i,
++			   (i > TX_PWR_CFG_9_IDX) ? "_EXT" : "",
++			   (unsigned long) regs[i]);
++}
++
+ /*
+  * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and
+  * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values,
+@@ -3010,9 +4044,9 @@ static u8 rt2800_compensate_txpower(stru
+  * EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to
+  * current conditions (i.e. band, bandwidth, temperature, user settings).
+  */
+-static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
+-				  struct ieee80211_channel *chan,
+-				  int power_level)
++static void rt2800_config_txpower_rt28xx(struct rt2x00_dev *rt2x00dev,
++					 struct ieee80211_channel *chan,
++					 int power_level)
+ {
+ 	u8 txpower, r1;
+ 	u16 eeprom;
+@@ -3080,8 +4114,8 @@ static void rt2800_config_txpower(struct
+ 		rt2800_register_read(rt2x00dev, offset, &reg);
+ 
+ 		/* read the next four txpower values */
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
+-				   &eeprom);
++		rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++					      i, &eeprom);
+ 
+ 		is_rate_b = i ? 0 : 1;
+ 		/*
+@@ -3129,8 +4163,8 @@ static void rt2800_config_txpower(struct
+ 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower);
+ 
+ 		/* read the next four txpower values */
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
+-				   &eeprom);
++		rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++					      i + 1, &eeprom);
+ 
+ 		is_rate_b = 0;
+ 		/*
+@@ -3184,6 +4218,16 @@ static void rt2800_config_txpower(struct
+ 	}
+ }
+ 
++static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
++				  struct ieee80211_channel *chan,
++				  int power_level)
++{
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
++	else
++		rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
++}
++
+ void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
+ {
+ 	rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan,
+@@ -3219,6 +4263,7 @@ void rt2800_vco_calibration(struct rt2x0
+ 		rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+ 		rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+ 		break;
++	case RF3053:
+ 	case RF3290:
+ 	case RF5360:
+ 	case RF5370:
+@@ -3442,17 +4487,25 @@ static int rt2800_init_registers(struct
+ 		return ret;
+ 
+ 	rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
++	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
++			   rt2800_get_beacon_offset(rt2x00dev, 0));
++	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
++			   rt2800_get_beacon_offset(rt2x00dev, 1));
++	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
++			   rt2800_get_beacon_offset(rt2x00dev, 2));
++	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
++			   rt2800_get_beacon_offset(rt2x00dev, 3));
+ 	rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
+ 
+ 	rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
++	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
++			   rt2800_get_beacon_offset(rt2x00dev, 4));
++	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
++			   rt2800_get_beacon_offset(rt2x00dev, 5));
++	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
++			   rt2800_get_beacon_offset(rt2x00dev, 6));
++	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
++			   rt2800_get_beacon_offset(rt2x00dev, 7));
+ 	rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
+ 
+ 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
+@@ -3528,7 +4581,8 @@ static int rt2800_init_registers(struct
+ 		if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+ 		    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
+ 		    rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
+-			rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++			rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
++					   &eeprom);
+ 			if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
+ 				rt2800_register_write(rt2x00dev, TX_SW_CFG2,
+ 						      0x0000002c);
+@@ -3559,6 +4613,23 @@ static int rt2800_init_registers(struct
+ 	} else if (rt2x00_rt(rt2x00dev, RT3572)) {
+ 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
++	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
++		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
++		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
++		if (rt2x00_rt_rev_lt(rt2x00dev, RT3593, REV_RT3593E)) {
++			rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
++					   &eeprom);
++			if (rt2x00_get_field16(eeprom,
++					       EEPROM_NIC_CONF1_DAC_TEST))
++				rt2800_register_write(rt2x00dev, TX_SW_CFG2,
++						      0x0000001f);
++			else
++				rt2800_register_write(rt2x00dev, TX_SW_CFG2,
++						      0x0000000f);
++		} else {
++			rt2800_register_write(rt2x00dev, TX_SW_CFG2,
++					      0x00000000);
++		}
+ 	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
+ 		   rt2x00_rt(rt2x00dev, RT5392) ||
+ 		   rt2x00_rt(rt2x00dev, RT5592)) {
+@@ -3786,14 +4857,8 @@ static int rt2800_init_registers(struct
+ 	/*
+ 	 * Clear all beacons
+ 	 */
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE0);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE1);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE2);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE3);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE4);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE5);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE6);
+-	rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE7);
++	for (i = 0; i < 8; i++)
++		rt2800_clear_beacon_register(rt2x00dev, i);
+ 
+ 	if (rt2x00_is_usb(rt2x00dev)) {
+ 		rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg);
+@@ -3989,7 +5054,7 @@ static void rt2800_disable_unused_dac_ad
+ 	u8 value;
+ 
+ 	rt2800_bbp_read(rt2x00dev, 138, &value);
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
+ 		value |= 0x20;
+ 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
+@@ -4332,6 +5397,22 @@ static void rt2800_init_bbp_3572(struct
+ 	rt2800_disable_unused_dac_adc(rt2x00dev);
+ }
+ 
++static void rt2800_init_bbp_3593(struct rt2x00_dev *rt2x00dev)
++{
++	rt2800_init_bbp_early(rt2x00dev);
++
++	rt2800_bbp_write(rt2x00dev, 79, 0x13);
++	rt2800_bbp_write(rt2x00dev, 80, 0x05);
++	rt2800_bbp_write(rt2x00dev, 81, 0x33);
++	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
++
++	rt2800_bbp_write(rt2x00dev, 84, 0x19);
++
++	/* Enable DC filter */
++	if (rt2x00_rt_rev_gte(rt2x00dev, RT3593, REV_RT3593E))
++		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
++}
++
+ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
+ {
+ 	int ant, div_mode;
+@@ -4402,7 +5483,7 @@ static void rt2800_init_bbp_53xx(struct
+ 
+ 	rt2800_disable_unused_dac_adc(rt2x00dev);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ 	div_mode = rt2x00_get_field16(eeprom,
+ 				      EEPROM_NIC_CONF1_ANT_DIVERSITY);
+ 	ant = (div_mode == 3) ? 1 : 0;
+@@ -4488,7 +5569,7 @@ static void rt2800_init_bbp_5592(struct
+ 
+ 	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ 	div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
+ 	ant = (div_mode == 3) ? 1 : 0;
+ 	rt2800_bbp_read(rt2x00dev, 152, &value);
+@@ -4547,6 +5628,9 @@ static void rt2800_init_bbp(struct rt2x0
+ 	case RT3572:
+ 		rt2800_init_bbp_3572(rt2x00dev);
+ 		break;
++	case RT3593:
++		rt2800_init_bbp_3593(rt2x00dev);
++		return;
+ 	case RT5390:
+ 	case RT5392:
+ 		rt2800_init_bbp_53xx(rt2x00dev);
+@@ -4557,7 +5641,8 @@ static void rt2800_init_bbp(struct rt2x0
+ 	}
+ 
+ 	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
++		rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_BBP_START, i,
++					      &eeprom);
+ 
+ 		if (eeprom != 0xffff && eeprom != 0x0000) {
+ 			reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
+@@ -4728,7 +5813,7 @@ static void rt2800_normal_mode_setup_3xx
+ 	if (rt2x00_rt(rt2x00dev, RT3090)) {
+ 		/*  Turn off unused DAC1 and ADC1 to reduce power consumption */
+ 		rt2800_bbp_read(rt2x00dev, 138, &bbp);
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ 		if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
+ 			rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
+ 		if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
+@@ -4771,6 +5856,42 @@ static void rt2800_normal_mode_setup_3xx
+ 	}
+ }
+ 
++static void rt2800_normal_mode_setup_3593(struct rt2x00_dev *rt2x00dev)
++{
++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++	u8 rfcsr;
++	u8 tx_gain;
++
++	rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR50_TX_LO2_EN, 0);
++	rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
++	tx_gain = rt2x00_get_field8(drv_data->txmixer_gain_24g,
++				    RFCSR17_TXMIXER_GAIN);
++	rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, tx_gain);
++	rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
++	rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0);
++	rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
++	rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
++	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
++
++	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
++	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
++
++	/* TODO: enable stream mode */
++}
++
+ static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev)
+ {
+ 	u8 reg;
+@@ -4778,7 +5899,7 @@ static void rt2800_normal_mode_setup_5xx
+ 
+ 	/*  Turn off unused DAC1 and ADC1 to reduce power consumption */
+ 	rt2800_bbp_read(rt2x00dev, 138, &reg);
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
+ 		rt2x00_set_field8(&reg, BBP138_RX_ADC1, 0);
+ 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
+@@ -4884,7 +6005,8 @@ static void rt2800_init_rfcsr_30xx(struc
+ 		rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+ 		if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+ 		    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
+-			rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++			rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
++					   &eeprom);
+ 			if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
+ 				rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+ 			else
+@@ -5152,6 +6274,136 @@ static void rt2800_init_rfcsr_3572(struc
+ 	rt2800_normal_mode_setup_3xxx(rt2x00dev);
+ }
+ 
++static void rt3593_post_bbp_init(struct rt2x00_dev *rt2x00dev)
++{
++	u8 bbp;
++	bool txbf_enabled = false; /* FIXME */
++
++	rt2800_bbp_read(rt2x00dev, 105, &bbp);
++	if (rt2x00dev->default_ant.rx_chain_num == 1)
++		rt2x00_set_field8(&bbp, BBP105_MLD, 0);
++	else
++		rt2x00_set_field8(&bbp, BBP105_MLD, 1);
++	rt2800_bbp_write(rt2x00dev, 105, bbp);
++
++	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
++
++	rt2800_bbp_write(rt2x00dev, 92, 0x02);
++	rt2800_bbp_write(rt2x00dev, 82, 0x82);
++	rt2800_bbp_write(rt2x00dev, 106, 0x05);
++	rt2800_bbp_write(rt2x00dev, 104, 0x92);
++	rt2800_bbp_write(rt2x00dev, 88, 0x90);
++	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
++	rt2800_bbp_write(rt2x00dev, 47, 0x48);
++	rt2800_bbp_write(rt2x00dev, 120, 0x50);
++
++	if (txbf_enabled)
++		rt2800_bbp_write(rt2x00dev, 163, 0xbd);
++	else
++		rt2800_bbp_write(rt2x00dev, 163, 0x9d);
++
++	/* SNR mapping */
++	rt2800_bbp_write(rt2x00dev, 142, 6);
++	rt2800_bbp_write(rt2x00dev, 143, 160);
++	rt2800_bbp_write(rt2x00dev, 142, 7);
++	rt2800_bbp_write(rt2x00dev, 143, 161);
++	rt2800_bbp_write(rt2x00dev, 142, 8);
++	rt2800_bbp_write(rt2x00dev, 143, 162);
++
++	/* ADC/DAC control */
++	rt2800_bbp_write(rt2x00dev, 31, 0x08);
++
++	/* RX AGC energy lower bound in log2 */
++	rt2800_bbp_write(rt2x00dev, 68, 0x0b);
++
++	/* FIXME: BBP 105 owerwrite? */
++	rt2800_bbp_write(rt2x00dev, 105, 0x04);
++
++}
++
++static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
++{
++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++	u32 reg;
++	u8 rfcsr;
++
++	/* Disable GPIO #4 and #7 function for LAN PE control */
++	rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
++	rt2x00_set_field32(&reg, GPIO_SWITCH_4, 0);
++	rt2x00_set_field32(&reg, GPIO_SWITCH_7, 0);
++	rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
++
++	/* Initialize default register values */
++	rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
++	rt2800_rfcsr_write(rt2x00dev, 3, 0x80);
++	rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
++	rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
++	rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
++	rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
++	rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
++	rt2800_rfcsr_write(rt2x00dev, 11, 0x40);
++	rt2800_rfcsr_write(rt2x00dev, 12, 0x4e);
++	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
++	rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
++	rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
++	rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
++	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
++	rt2800_rfcsr_write(rt2x00dev, 32, 0x78);
++	rt2800_rfcsr_write(rt2x00dev, 33, 0x3b);
++	rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
++	rt2800_rfcsr_write(rt2x00dev, 35, 0xe0);
++	rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
++	rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
++	rt2800_rfcsr_write(rt2x00dev, 44, 0xd3);
++	rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
++	rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
++	rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
++	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
++	rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
++	rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
++	rt2800_rfcsr_write(rt2x00dev, 53, 0x18);
++	rt2800_rfcsr_write(rt2x00dev, 54, 0x18);
++	rt2800_rfcsr_write(rt2x00dev, 55, 0x18);
++	rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
++	rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
++
++	/* Initiate calibration */
++	/* TODO: use rt2800_rf_init_calibration ? */
++	rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
++	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
++
++	rt2800_adjust_freq_offset(rt2x00dev);
++
++	rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr);
++	rt2x00_set_field8(&rfcsr, RFCSR18_XO_TUNE_BYPASS, 1);
++	rt2800_rfcsr_write(rt2x00dev, 18, rfcsr);
++
++	rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
++	rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
++	rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
++	rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
++	usleep_range(1000, 1500);
++	rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
++	rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
++	rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
++
++	/* Set initial values for RX filter calibration */
++	drv_data->calibration_bw20 = 0x1f;
++	drv_data->calibration_bw40 = 0x2f;
++
++	/* Save BBP 25 & 26 values for later use in channel switching */
++	rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25);
++	rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
++
++	rt2800_led_open_drain_enable(rt2x00dev);
++	rt2800_normal_mode_setup_3593(rt2x00dev);
++
++	rt3593_post_bbp_init(rt2x00dev);
++
++	/* TODO: enable stream mode support */
++}
++
+ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
+ {
+ 	rt2800_rf_init_calibration(rt2x00dev, 2);
+@@ -5380,6 +6632,9 @@ static void rt2800_init_rfcsr(struct rt2
+ 	case RT3572:
+ 		rt2800_init_rfcsr_3572(rt2x00dev);
+ 		break;
++	case RT3593:
++		rt2800_init_rfcsr_3593(rt2x00dev);
++		break;
+ 	case RT5390:
+ 		rt2800_init_rfcsr_5390(rt2x00dev);
+ 		break;
+@@ -5456,15 +6711,15 @@ int rt2800_enable_radio(struct rt2x00_de
+ 	/*
+ 	 * Initialize LED control
+ 	 */
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
+ 	rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
+ 			   word & 0xff, (word >> 8) & 0xff);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
+ 	rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
+ 			   word & 0xff, (word >> 8) & 0xff);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
+ 	rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
+ 			   word & 0xff, (word >> 8) & 0xff);
+ 
+@@ -5560,6 +6815,34 @@ int rt2800_read_eeprom_efuse(struct rt2x
+ }
+ EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
+ 
++static u8 rt2800_get_txmixer_gain_24g(struct rt2x00_dev *rt2x00dev)
++{
++	u16 word;
++
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		return 0;
++
++	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
++	if ((word & 0x00ff) != 0x00ff)
++		return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
++
++	return 0;
++}
++
++static u8 rt2800_get_txmixer_gain_5g(struct rt2x00_dev *rt2x00dev)
++{
++	u16 word;
++
++	if (rt2x00_rt(rt2x00dev, RT3593))
++		return 0;
++
++	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
++	if ((word & 0x00ff) != 0x00ff)
++		return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
++
++	return 0;
++}
++
+ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+ {
+ 	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+@@ -5578,18 +6861,18 @@ static int rt2800_validate_eeprom(struct
+ 	/*
+ 	 * Start validation of the data that has been read.
+ 	 */
+-	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
++	mac = rt2800_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+ 	if (!is_valid_ether_addr(mac)) {
+ 		eth_random_addr(mac);
+ 		rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+ 	}
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
+ 	if (word == 0xffff) {
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+ 		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
+ 	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
+ 		   rt2x00_rt(rt2x00dev, RT2872)) {
+@@ -5598,10 +6881,10 @@ static int rt2800_validate_eeprom(struct
+ 		 */
+ 		if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
+ 			rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+ 	}
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
+ 	if (word == 0xffff) {
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
+@@ -5618,24 +6901,24 @@ static int rt2800_validate_eeprom(struct
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
+ 		rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
+ 		rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word);
+ 	}
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
+ 	if ((word & 0x00ff) == 0x00ff) {
+ 		rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+ 		rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word);
+ 	}
+ 	if ((word & 0xff00) == 0xff00) {
+ 		rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
+ 				   LED_MODE_TXRX_ACTIVITY);
+ 		rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
+-		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
+ 		rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word);
+ 	}
+ 
+@@ -5644,56 +6927,61 @@ static int rt2800_validate_eeprom(struct
+ 	 * lna0 as correct value. Note that EEPROM_LNA
+ 	 * is never validated.
+ 	 */
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
+ 	default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
+ 		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
+ 		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
+-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
++	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
+-	if ((word & 0x00ff) != 0x00ff) {
+-		drv_data->txmixer_gain_24g =
+-			rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
+-	} else {
+-		drv_data->txmixer_gain_24g = 0;
+-	}
++	drv_data->txmixer_gain_24g = rt2800_get_txmixer_gain_24g(rt2x00dev);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
+ 		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
+-	if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+-	    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+-		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+-				   default_lna_gain);
+-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
+-
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
+-	if ((word & 0x00ff) != 0x00ff) {
+-		drv_data->txmixer_gain_5g =
+-			rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
+-	} else {
+-		drv_data->txmixer_gain_5g = 0;
++	if (!rt2x00_rt(rt2x00dev, RT3593)) {
++		if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
++		    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
++			rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
++					   default_lna_gain);
+ 	}
++	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
++
++	drv_data->txmixer_gain_5g = rt2800_get_txmixer_gain_5g(rt2x00dev);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
+ 		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
+ 		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
+-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
++	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
+ 		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
+-	if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+-	    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+-		rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+-				   default_lna_gain);
+-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
++	if (!rt2x00_rt(rt2x00dev, RT3593)) {
++		if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
++		    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
++			rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
++					   default_lna_gain);
++	}
++	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
++
++	if (rt2x00_rt(rt2x00dev, RT3593)) {
++		rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word);
++		if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
++		    rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
++			rt2x00_set_field16(&word, EEPROM_EXT_LNA2_A1,
++					   default_lna_gain);
++		if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A2) == 0x00 ||
++		    rt2x00_get_field16(word, EEPROM_EXT_LNA2_A2) == 0xff)
++			rt2x00_set_field16(&word, EEPROM_EXT_LNA2_A1,
++					   default_lna_gain);
++		rt2800_eeprom_write(rt2x00dev, EEPROM_EXT_LNA2, word);
++	}
+ 
+ 	return 0;
+ }
+@@ -5707,7 +6995,7 @@ static int rt2800_init_eeprom(struct rt2
+ 	/*
+ 	 * Read EEPROM word for configuration.
+ 	 */
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ 
+ 	/*
+ 	 * Identify RF chipset by EEPROM value
+@@ -5717,7 +7005,7 @@ static int rt2800_init_eeprom(struct rt2
+ 	if (rt2x00_rt(rt2x00dev, RT3290) ||
+ 	    rt2x00_rt(rt2x00dev, RT5390) ||
+ 	    rt2x00_rt(rt2x00dev, RT5392))
+-		rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
++		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+ 	else
+ 		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+ 
+@@ -5731,6 +7019,7 @@ static int rt2800_init_eeprom(struct rt2
+ 	case RF3021:
+ 	case RF3022:
+ 	case RF3052:
++	case RF3053:
+ 	case RF3290:
+ 	case RF3320:
+ 	case RF3322:
+@@ -5757,7 +7046,7 @@ static int rt2800_init_eeprom(struct rt2
+ 	rt2x00dev->default_ant.rx_chain_num =
+ 	    rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ 
+ 	if (rt2x00_rt(rt2x00dev, RT3070) ||
+ 	    rt2x00_rt(rt2x00dev, RT3090) ||
+@@ -5810,7 +7099,7 @@ static int rt2800_init_eeprom(struct rt2
+ 	/*
+ 	 * Read frequency offset and RF programming sequence.
+ 	 */
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ 	rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
+ 
+ 	/*
+@@ -5827,7 +7116,7 @@ static int rt2800_init_eeprom(struct rt2
+ 	/*
+ 	 * Check if support EIRP tx power limit feature.
+ 	 */
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
+ 
+ 	if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
+ 					EIRP_MAX_TX_POWER_LIMIT)
+@@ -6109,12 +7398,79 @@ static const struct rf_channel rf_vals_5
+ 	{196, 83, 0, 12, 1},
+ };
+ 
++static const struct rf_channel rf_vals_3053[] = {
++	/* Channel, N, R, K */
++	{1, 241, 2, 2},
++	{2, 241, 2, 7},
++	{3, 242, 2, 2},
++	{4, 242, 2, 7},
++	{5, 243, 2, 2},
++	{6, 243, 2, 7},
++	{7, 244, 2, 2},
++	{8, 244, 2, 7},
++	{9, 245, 2, 2},
++	{10, 245, 2, 7},
++	{11, 246, 2, 2},
++	{12, 246, 2, 7},
++	{13, 247, 2, 2},
++	{14, 248, 2, 4},
++
++	{36, 0x56, 0, 4},
++	{38, 0x56, 0, 6},
++	{40, 0x56, 0, 8},
++	{44, 0x57, 0, 0},
++	{46, 0x57, 0, 2},
++	{48, 0x57, 0, 4},
++	{52, 0x57, 0, 8},
++	{54, 0x57, 0, 10},
++	{56, 0x58, 0, 0},
++	{60, 0x58, 0, 4},
++	{62, 0x58, 0, 6},
++	{64, 0x58, 0, 8},
++
++	{100, 0x5B, 0, 8},
++	{102, 0x5B, 0, 10},
++	{104, 0x5C, 0, 0},
++	{108, 0x5C, 0, 4},
++	{110, 0x5C, 0, 6},
++	{112, 0x5C, 0, 8},
++
++	/* NOTE: Channel 114 has been removed intentionally.
++	 * The EEPROM contains no TX power values for that,
++	 * and it is disabled in the vendor driver as well.
++	 */
++
++	{116, 0x5D, 0, 0},
++	{118, 0x5D, 0, 2},
++	{120, 0x5D, 0, 4},
++	{124, 0x5D, 0, 8},
++	{126, 0x5D, 0, 10},
++	{128, 0x5E, 0, 0},
++	{132, 0x5E, 0, 4},
++	{134, 0x5E, 0, 6},
++	{136, 0x5E, 0, 8},
++	{140, 0x5F, 0, 0},
++
++	{149, 0x5F, 0, 9},
++	{151, 0x5F, 0, 11},
++	{153, 0x60, 0, 1},
++	{157, 0x60, 0, 5},
++	{159, 0x60, 0, 7},
++	{161, 0x60, 0, 9},
++	{165, 0x61, 0, 1},
++	{167, 0x61, 0, 3},
++	{169, 0x61, 0, 5},
++	{171, 0x61, 0, 7},
++	{173, 0x61, 0, 9},
++};
++
+ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ {
+ 	struct hw_mode_spec *spec = &rt2x00dev->spec;
+ 	struct channel_info *info;
+ 	char *default_power1;
+ 	char *default_power2;
++	char *default_power3;
+ 	unsigned int i;
+ 	u16 eeprom;
+ 	u32 reg;
+@@ -6149,7 +7505,7 @@ static int rt2800_probe_hw_mode(struct r
+ 
+ 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
+ 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
+-				rt2x00_eeprom_addr(rt2x00dev,
++				rt2800_eeprom_addr(rt2x00dev,
+ 						   EEPROM_MAC_ADDR_0));
+ 
+ 	/*
+@@ -6165,7 +7521,7 @@ static int rt2800_probe_hw_mode(struct r
+ 	rt2x00dev->hw->max_report_rates = 7;
+ 	rt2x00dev->hw->max_rate_tries = 1;
+ 
+-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ 
+ 	/*
+ 	 * Initialize hw_mode information.
+@@ -6200,6 +7556,10 @@ static int rt2800_probe_hw_mode(struct r
+ 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
+ 		spec->num_channels = ARRAY_SIZE(rf_vals_3x);
+ 		spec->channels = rf_vals_3x;
++	} else if (rt2x00_rf(rt2x00dev, RF3053)) {
++		spec->supported_bands |= SUPPORT_BAND_5GHZ;
++		spec->num_channels = ARRAY_SIZE(rf_vals_3053);
++		spec->channels = rf_vals_3053;
+ 	} else if (rt2x00_rf(rt2x00dev, RF5592)) {
+ 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
+ 
+@@ -6265,21 +7625,40 @@ static int rt2800_probe_hw_mode(struct r
+ 
+ 	spec->channels_info = info;
+ 
+-	default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+-	default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
++	default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
++	default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
++
++	if (rt2x00dev->default_ant.tx_chain_num > 2)
++		default_power3 = rt2800_eeprom_addr(rt2x00dev,
++						    EEPROM_EXT_TXPOWER_BG3);
++	else
++		default_power3 = NULL;
+ 
+ 	for (i = 0; i < 14; i++) {
+ 		info[i].default_power1 = default_power1[i];
+ 		info[i].default_power2 = default_power2[i];
++		if (default_power3)
++			info[i].default_power3 = default_power3[i];
+ 	}
+ 
+ 	if (spec->num_channels > 14) {
+-		default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+-		default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
++		default_power1 = rt2800_eeprom_addr(rt2x00dev,
++						    EEPROM_TXPOWER_A1);
++		default_power2 = rt2800_eeprom_addr(rt2x00dev,
++						    EEPROM_TXPOWER_A2);
++
++		if (rt2x00dev->default_ant.tx_chain_num > 2)
++			default_power3 =
++				rt2800_eeprom_addr(rt2x00dev,
++						   EEPROM_EXT_TXPOWER_A3);
++		else
++			default_power3 = NULL;
+ 
+ 		for (i = 14; i < spec->num_channels; i++) {
+ 			info[i].default_power1 = default_power1[i - 14];
+ 			info[i].default_power2 = default_power2[i - 14];
++			if (default_power3)
++				info[i].default_power3 = default_power3[i - 14];
+ 		}
+ 	}
+ 
+@@ -6290,6 +7669,7 @@ static int rt2800_probe_hw_mode(struct r
+ 	case RF3022:
+ 	case RF3320:
+ 	case RF3052:
++	case RF3053:
+ 	case RF3290:
+ 	case RF5360:
+ 	case RF5370:
+@@ -6328,6 +7708,7 @@ static int rt2800_probe_rt(struct rt2x00
+ 	case RT3352:
+ 	case RT3390:
+ 	case RT3572:
++	case RT3593:
+ 	case RT5390:
+ 	case RT5392:
+ 	case RT5592:
+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -226,4 +226,8 @@ int rt2800_get_survey(struct ieee80211_h
+ 		      struct survey_info *survey);
+ void rt2800_disable_wpdma(struct rt2x00_dev *rt2x00dev);
+ 
++void rt2800_get_txwi_rxwi_size(struct rt2x00_dev *rt2x00dev,
++			       unsigned short *txwi_size,
++			       unsigned short *rxwi_size);
++
+ #endif /* RT2800LIB_H */
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -507,9 +507,13 @@ static int rt2800pci_init_registers(stru
+ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+ 
+ 	if (rt2x00_is_pcie(rt2x00dev) &&
+-	    (rt2x00_rt(rt2x00dev, RT3572) ||
++	    (rt2x00_rt(rt2x00dev, RT3090) ||
++	     rt2x00_rt(rt2x00dev, RT3390) ||
++	     rt2x00_rt(rt2x00dev, RT3572) ||
++	     rt2x00_rt(rt2x00dev, RT3593) ||
+ 	     rt2x00_rt(rt2x00dev, RT5390) ||
+-	     rt2x00_rt(rt2x00dev, RT5392))) {
++	     rt2x00_rt(rt2x00dev, RT5392) ||
++	     rt2x00_rt(rt2x00dev, RT5592))) {
+ 		rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, &reg);
+ 		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
+ 		rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
+@@ -1189,12 +1193,17 @@ static const struct rt2x00lib_ops rt2800
+ 
+ static void rt2800pci_queue_init(struct data_queue *queue)
+ {
++	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
++	unsigned short txwi_size, rxwi_size;
++
++	rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size);
++
+ 	switch (queue->qid) {
+ 	case QID_RX:
+ 		queue->limit = 128;
+ 		queue->data_size = AGGREGATION_SIZE;
+ 		queue->desc_size = RXD_DESC_SIZE;
+-		queue->winfo_size = RXWI_DESC_SIZE_4WORDS;
++		queue->winfo_size = rxwi_size;
+ 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+ 		break;
+ 
+@@ -1205,7 +1214,7 @@ static void rt2800pci_queue_init(struct
+ 		queue->limit = 64;
+ 		queue->data_size = AGGREGATION_SIZE;
+ 		queue->desc_size = TXD_DESC_SIZE;
+-		queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
++		queue->winfo_size = txwi_size;
+ 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+ 		break;
+ 
+@@ -1213,7 +1222,7 @@ static void rt2800pci_queue_init(struct
+ 		queue->limit = 8;
+ 		queue->data_size = 0; /* No DMA required for beacons */
+ 		queue->desc_size = TXD_DESC_SIZE;
+-		queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
++		queue->winfo_size = txwi_size;
+ 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+ 		break;
+ 
+--- a/drivers/net/wireless/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
+@@ -854,13 +854,7 @@ static void rt2800usb_queue_init(struct
+ 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ 	unsigned short txwi_size, rxwi_size;
+ 
+-	if (rt2x00_rt(rt2x00dev, RT5592)) {
+-		txwi_size = TXWI_DESC_SIZE_5WORDS;
+-		rxwi_size = RXWI_DESC_SIZE_6WORDS;
+-	} else {
+-		txwi_size = TXWI_DESC_SIZE_4WORDS;
+-		rxwi_size = RXWI_DESC_SIZE_4WORDS;
+-	}
++	rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size);
+ 
+ 	switch (queue->qid) {
+ 	case QID_RX:
+@@ -1194,6 +1188,40 @@ static struct usb_device_id rt2800usb_de
+ 	/* Zinwell */
+ 	{ USB_DEVICE(0x5a57, 0x0284) },
+ #endif
++#ifdef CPTCFG_RT2800USB_RT3573
++	/* AirLive */
++	{ USB_DEVICE(0x1b75, 0x7733) },
++	/* ASUS */
++	{ USB_DEVICE(0x0b05, 0x17bc) },
++	{ USB_DEVICE(0x0b05, 0x17ad) },
++	/* Belkin */
++	{ USB_DEVICE(0x050d, 0x1103) },
++	/* Cameo */
++	{ USB_DEVICE(0x148f, 0xf301) },
++	/* Edimax */
++	{ USB_DEVICE(0x7392, 0x7733) },
++	/* Hawking */
++	{ USB_DEVICE(0x0e66, 0x0020) },
++	{ USB_DEVICE(0x0e66, 0x0021) },
++	/* I-O DATA */
++	{ USB_DEVICE(0x04bb, 0x094e) },
++	/* Linksys */
++	{ USB_DEVICE(0x13b1, 0x003b) },
++	/* Logitec */
++	{ USB_DEVICE(0x0789, 0x016b) },
++	/* NETGEAR */
++	{ USB_DEVICE(0x0846, 0x9012) },
++	{ USB_DEVICE(0x0846, 0x9019) },
++	/* Planex */
++	{ USB_DEVICE(0x2019, 0xed19) },
++	/* Ralink */
++	{ USB_DEVICE(0x148f, 0x3573) },
++	/* Sitecom */
++	{ USB_DEVICE(0x0df6, 0x0067) },
++	{ USB_DEVICE(0x0df6, 0x006a) },
++	/* ZyXEL */
++	{ USB_DEVICE(0x0586, 0x3421) },
++#endif
+ #ifdef CPTCFG_RT2800USB_RT53XX
+ 	/* Arcadyan */
+ 	{ USB_DEVICE(0x043e, 0x7a12) },
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -211,6 +211,7 @@ struct channel_info {
+ 	short max_power;
+ 	short default_power1;
+ 	short default_power2;
++	short default_power3;
+ };
+ 
+ /*

+ 6 - 6
package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch

@@ -101,7 +101,7 @@
 +}
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -549,6 +549,7 @@ struct rt2x00lib_ops {
+@@ -550,6 +550,7 @@ struct rt2x00lib_ops {
  			       const u8 *data, const size_t len);
  	int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
  			      const u8 *data, const size_t len);
@@ -109,7 +109,7 @@
  
  	/*
  	 * Device initialization/deinitialization handlers.
-@@ -705,6 +706,7 @@ enum rt2x00_capability_flags {
+@@ -706,6 +707,7 @@ enum rt2x00_capability_flags {
  	REQUIRE_SW_SEQNO,
  	REQUIRE_HT_TX_DESC,
  	REQUIRE_PS_AUTOWAKE,
@@ -117,7 +117,7 @@
  
  	/*
  	 * Capabilities
-@@ -974,6 +976,11 @@ struct rt2x00_dev {
+@@ -975,6 +977,11 @@ struct rt2x00_dev {
  	const struct firmware *fw;
  
  	/*
@@ -164,7 +164,7 @@
  	select RT2X00_LIB_CRYPTO
  	depends on CRC_CCITT
  	depends on EEPROM_93CX6
-@@ -238,6 +239,9 @@ config RT2X00_LIB_FIRMWARE
+@@ -244,6 +245,9 @@ config RT2X00_LIB_FIRMWARE
  config RT2X00_LIB_CRYPTO
  	boolean
  
@@ -186,7 +186,7 @@
  obj-$(CPTCFG_RT2X00_LIB_MMIO)		+= rt2x00mmio.o
 --- a/drivers/net/wireless/rt2x00/rt2800pci.c
 +++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-@@ -90,25 +90,11 @@ static void rt2800pci_mcu_status(struct 
+@@ -90,25 +90,11 @@ static void rt2800pci_mcu_status(struct
  	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
  }
  
@@ -234,7 +234,7 @@
   * Initialization functions.
   */
  static bool rt2800pci_get_entry_state(struct queue_entry *entry)
-@@ -1156,6 +1156,7 @@ static const struct rt2x00lib_ops rt2800
+@@ -1160,6 +1160,7 @@ static const struct rt2x00lib_ops rt2800
  	.get_firmware_name	= rt2800pci_get_firmware_name,
  	.check_firmware		= rt2800_check_firmware,
  	.load_firmware		= rt2800_load_firmware,

+ 2 - 2
package/kernel/mac80211/patches/605-rt2x00-pci-eeprom.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/rt2x00/rt2800pci.c
 +++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-@@ -90,7 +90,7 @@ static void rt2800pci_mcu_status(struct 
+@@ -90,7 +90,7 @@ static void rt2800pci_mcu_status(struct
  	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
  }
  
@@ -9,7 +9,7 @@
  {
  	memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
  	return 0;
-@@ -1093,8 +1093,9 @@ static int rt2800pci_read_eeprom(struct 
+@@ -1097,8 +1097,9 @@ static int rt2800pci_read_eeprom(struct
  {
  	int retval;
  

+ 1 - 1
package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch

@@ -37,7 +37,7 @@
  		num_rates += 4;
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -414,6 +414,7 @@ struct hw_mode_spec {
+@@ -415,6 +415,7 @@ struct hw_mode_spec {
  	unsigned int supported_bands;
  #define SUPPORT_BAND_2GHZ	0x00000001
  #define SUPPORT_BAND_5GHZ	0x00000002

+ 1 - 1
package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch

@@ -31,7 +31,7 @@
  {
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -1326,6 +1326,7 @@ static inline void rt2x00debug_dump_fram
+@@ -1327,6 +1327,7 @@ static inline void rt2x00debug_dump_fram
   */
  u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
  			 struct ieee80211_vif *vif);

+ 30 - 19
package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -2631,15 +2631,18 @@ static void rt2800_config_channel(struct
+@@ -3186,11 +3186,17 @@ static void rt2800_config_channel(struct
  	/*
  	 * Change BBP settings
  	 */
@@ -15,6 +15,17 @@
  		rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
 +		rt2800_bbp_write(rt2x00dev, 86, 0x38);
 +		rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+ 	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
+ 		if (rf->channel > 14) {
+ 			/* Disable CCK Packet detection on 5GHz */
+@@ -3204,14 +3210,8 @@ static void rt2800_config_channel(struct
+ 		else
+ 			rt2800_bbp_write(rt2x00dev, 105, 0x34);
+ 
+-		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+-		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+-		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ 		rt2800_bbp_write(rt2x00dev, 77, 0x98);
  	} else {
 -		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
 -		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
@@ -22,7 +33,7 @@
  		rt2800_bbp_write(rt2x00dev, 86, 0);
  	}
  
-@@ -4971,6 +4974,12 @@ static void rt2800_init_rfcsr_3290(struc
+@@ -6086,6 +6086,12 @@ static void rt2800_init_rfcsr_3290(struc
  
  static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
  {
@@ -35,7 +46,7 @@
  	rt2800_rf_init_calibration(rt2x00dev, 30);
  
  	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
-@@ -5006,15 +5015,30 @@ static void rt2800_init_rfcsr_3352(struc
+@@ -6121,15 +6127,30 @@ static void rt2800_init_rfcsr_3352(struc
  	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
  	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
  	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
@@ -69,7 +80,7 @@
  	rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
  	rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
  	rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
-@@ -5022,15 +5046,20 @@ static void rt2800_init_rfcsr_3352(struc
+@@ -6137,15 +6158,20 @@ static void rt2800_init_rfcsr_3352(struc
  	rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
  	rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
  	rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
@@ -99,15 +110,15 @@
  	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
  	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
  	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
-@@ -5715,6 +5744,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -6996,6 +7022,7 @@ static int rt2800_init_eeprom(struct rt2
  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
  	 */
  	if (rt2x00_rt(rt2x00dev, RT3290) ||
 +	    rt2x00_rt(rt2x00dev, RT3352) ||
  	    rt2x00_rt(rt2x00dev, RT5390) ||
  	    rt2x00_rt(rt2x00dev, RT5392))
- 		rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-@@ -5804,7 +5834,8 @@ static int rt2800_init_eeprom(struct rt2
+ 		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+@@ -7086,7 +7113,8 @@ static int rt2800_init_eeprom(struct rt2
  	/*
  	 * Detect if this device has Bluetooth co-existence.
  	 */
@@ -117,14 +128,14 @@
  		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
  
  	/*
-@@ -5833,6 +5864,22 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7115,6 +7143,22 @@ static int rt2800_init_eeprom(struct rt2
  					EIRP_MAX_TX_POWER_LIMIT)
  		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
  
 +	/*
 +	 * Detect if device uses internal or external PA
 +	 */
-+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++	rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
 +
 +	if (rt2x00_rt(rt2x00dev, RT3352)) {
 +		if (!rt2x00_get_field16(eeprom,
@@ -142,8 +153,8 @@
  
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -2153,6 +2153,12 @@ struct mac_iveiv_entry {
- #define RFCSR31_RX_CALIB		FIELD8(0x7f)
+@@ -2299,6 +2299,12 @@ struct mac_iveiv_entry {
+ #define RFCSR36_RF_BS			FIELD8(0x80)
  
  /*
 + * RFCSR 34:
@@ -155,7 +166,7 @@
   * RFCSR 38:
   */
  #define RFCSR38_RX_LO1_EN		FIELD8(0x20)
-@@ -2163,6 +2169,18 @@ struct mac_iveiv_entry {
+@@ -2310,6 +2316,18 @@ struct mac_iveiv_entry {
  #define RFCSR39_RX_LO2_EN		FIELD8(0x80)
  
  /*
@@ -174,25 +185,25 @@
   * RFCSR 49:
   */
  #define RFCSR49_TX			FIELD8(0x3f)
-@@ -2172,6 +2190,8 @@ struct mac_iveiv_entry {
+@@ -2322,6 +2340,8 @@ struct mac_iveiv_entry {
   * RFCSR 50:
   */
  #define RFCSR50_TX			FIELD8(0x3f)
 +#define RFCSR50_TX0_EXT_PA		FIELD8(0x02)
 +#define RFCSR50_TX1_EXT_PA		FIELD8(0x10)
  #define RFCSR50_EP			FIELD8(0xc0)
- 
- /*
-@@ -2260,6 +2280,8 @@ struct mac_iveiv_entry {
+ /* bits for RT3593 */
+ #define RFCSR50_TX_LO1_EN		FIELD8(0x20)
+@@ -2469,6 +2489,8 @@ enum rt2800_eeprom_word {
   * INTERNAL_TX_ALC: 0: disable, 1: enable
   * BT_COEXIST: 0: disable, 1: enable
   * DAC_TEST: 0: disable, 1: enable
 + * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352)
 + * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352)
   */
- #define	EEPROM_NIC_CONF1		0x001b
  #define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
-@@ -2277,6 +2299,8 @@ struct mac_iveiv_entry {
+ #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC		FIELD16(0x0002)
+@@ -2485,6 +2507,8 @@ enum rt2800_eeprom_word {
  #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC		FIELD16(0x2000)
  #define EEPROM_NIC_CONF1_BT_COEXIST		FIELD16(0x4000)
  #define EEPROM_NIC_CONF1_DAC_TEST		FIELD16(0x8000)
@@ -203,7 +214,7 @@
   * EEPROM frequency
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -726,6 +726,8 @@ enum rt2x00_capability_flags {
+@@ -727,6 +727,8 @@ enum rt2x00_capability_flags {
  	CAPABILITY_DOUBLE_ANTENNA,
  	CAPABILITY_BT_COEXIST,
  	CAPABILITY_VCO_RECALIBRATION,

+ 8 - 8
package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch

@@ -1,7 +1,7 @@
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -6156,6 +6156,27 @@ static const struct rf_channel rf_vals_5
- 	{196, 83, 0, 12, 1},
+@@ -7501,6 +7501,27 @@ static const struct rf_channel rf_vals_3
+ 	{173, 0x61, 0, 9},
  };
  
 +/*
@@ -28,7 +28,7 @@
  static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
  {
  	struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -6235,7 +6256,6 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7581,7 +7602,6 @@ static int rt2800_probe_hw_mode(struct r
  		   rt2x00_rf(rt2x00dev, RF3022) ||
  		   rt2x00_rf(rt2x00dev, RF3290) ||
  		   rt2x00_rf(rt2x00dev, RF3320) ||
@@ -36,7 +36,7 @@
  		   rt2x00_rf(rt2x00dev, RF5360) ||
  		   rt2x00_rf(rt2x00dev, RF5370) ||
  		   rt2x00_rf(rt2x00dev, RF5372) ||
-@@ -6243,6 +6263,12 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7589,6 +7609,12 @@ static int rt2800_probe_hw_mode(struct r
  		   rt2x00_rf(rt2x00dev, RF5392)) {
  		spec->num_channels = 14;
  		spec->channels = rf_vals_3x;
@@ -49,7 +49,7 @@
  	} else if (rt2x00_rf(rt2x00dev, RF3052)) {
  		spec->supported_bands |= SUPPORT_BAND_5GHZ;
  		spec->num_channels = ARRAY_SIZE(rf_vals_3x);
-@@ -6390,6 +6416,19 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7761,6 +7787,19 @@ static int rt2800_probe_rt(struct rt2x00
  	return 0;
  }
  
@@ -69,7 +69,7 @@
  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
  {
  	int retval;
-@@ -6419,6 +6458,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -7790,6 +7829,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
  
  	/*
@@ -87,7 +87,7 @@
  	retval = rt2800_probe_hw_mode(rt2x00dev);
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -409,6 +409,7 @@ static inline struct rt2x00_intf* vif_to
+@@ -410,6 +410,7 @@ static inline struct rt2x00_intf* vif_to
   * @channels: Device/chipset specific channel values (See &struct rf_channel).
   * @channels_info: Additional information for channels (See &struct channel_info).
   * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
@@ -95,7 +95,7 @@
   */
  struct hw_mode_spec {
  	unsigned int supported_bands;
-@@ -425,6 +426,7 @@ struct hw_mode_spec {
+@@ -426,6 +427,7 @@ struct hw_mode_spec {
  	const struct channel_info *channels_info;
  
  	struct ieee80211_sta_ht_cap ht;

+ 1 - 1
package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch

@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800pci.c
 +++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-@@ -1309,11 +1309,18 @@ static int rt2800soc_probe(struct platfo
+@@ -1318,11 +1318,18 @@ static int rt2800soc_probe(struct platfo
  	return rt2x00soc_probe(pdev, &rt2800pci_ops);
  }
  

+ 1 - 1
package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch

@@ -8,7 +8,7 @@
  
  #include "rt2x00.h"
  #include "rt2800lib.h"
-@@ -6418,13 +6419,14 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7789,13 +7790,14 @@ static int rt2800_probe_rt(struct rt2x00
  
  int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
  {

+ 26 - 26
package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch

@@ -10,7 +10,7 @@
  #define RF5372				0x5372
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -2141,6 +2141,15 @@ static void rt2800_config_channel_rf53xx
+@@ -2675,6 +2675,15 @@ static void rt2800_config_channel_rf53xx
  	if (rf->channel <= 14) {
  		int idx = rf->channel-1;
  
@@ -26,7 +26,7 @@
  		if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
  			if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
  				/* r55/r59 value array of channel 1~14 */
-@@ -2598,6 +2607,7 @@ static void rt2800_config_channel(struct
+@@ -3153,6 +3162,7 @@ static void rt2800_config_channel(struct
  	case RF3322:
  		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
  		break;
@@ -34,7 +34,7 @@
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -2614,6 +2624,7 @@ static void rt2800_config_channel(struct
+@@ -3169,6 +3179,7 @@ static void rt2800_config_channel(struct
  
  	if (rt2x00_rf(rt2x00dev, RF3290) ||
  	    rt2x00_rf(rt2x00dev, RF3322) ||
@@ -42,7 +42,7 @@
  	    rt2x00_rf(rt2x00dev, RF5360) ||
  	    rt2x00_rf(rt2x00dev, RF5370) ||
  	    rt2x00_rf(rt2x00dev, RF5372) ||
-@@ -2778,7 +2789,8 @@ static void rt2800_config_channel(struct
+@@ -3393,7 +3404,8 @@ static void rt2800_config_channel(struct
  	/*
  	 * Clear update flag
  	 */
@@ -52,15 +52,15 @@
  		rt2800_bbp_read(rt2x00dev, 49, &bbp);
  		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
  		rt2800_bbp_write(rt2x00dev, 49, bbp);
-@@ -3224,6 +3236,7 @@ void rt2800_vco_calibration(struct rt2x0
- 		rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+@@ -4259,6 +4271,7 @@ void rt2800_vco_calibration(struct rt2x0
  		break;
+ 	case RF3053:
  	case RF3290:
 +	case RF5350:
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -3569,6 +3582,8 @@ static int rt2800_init_registers(struct 
+@@ -4630,6 +4643,8 @@ static int rt2800_init_registers(struct
  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
  		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -69,7 +69,7 @@
  	} else {
  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-@@ -4216,9 +4231,13 @@ static void rt2800_init_bbp_3352(struct 
+@@ -5271,9 +5286,13 @@ static void rt2800_init_bbp_3352(struct
  
  	rt2800_bbp_write(rt2x00dev, 82, 0x62);
  
@@ -86,7 +86,7 @@
  
  	rt2800_bbp_write(rt2x00dev, 86, 0x38);
  
-@@ -4232,9 +4251,13 @@ static void rt2800_init_bbp_3352(struct 
+@@ -5287,9 +5306,13 @@ static void rt2800_init_bbp_3352(struct
  
  	rt2800_bbp_write(rt2x00dev, 104, 0x92);
  
@@ -103,7 +103,7 @@
  
  	rt2800_bbp_write(rt2x00dev, 120, 0x50);
  
-@@ -4259,6 +4282,13 @@ static void rt2800_init_bbp_3352(struct 
+@@ -5314,6 +5337,13 @@ static void rt2800_init_bbp_3352(struct
  	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
  
  	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
@@ -117,7 +117,7 @@
  }
  
  static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
-@@ -4543,6 +4573,7 @@ static void rt2800_init_bbp(struct rt2x0
+@@ -5614,6 +5644,7 @@ static void rt2800_init_bbp(struct rt2x0
  		rt2800_init_bbp_3290(rt2x00dev);
  		break;
  	case RT3352:
@@ -125,8 +125,8 @@
  		rt2800_init_bbp_3352(rt2x00dev);
  		break;
  	case RT3390:
-@@ -5182,6 +5213,76 @@ static void rt2800_init_rfcsr_3572(struc
- 	rt2800_normal_mode_setup_3xxx(rt2x00dev);
+@@ -6424,6 +6455,76 @@ static void rt2800_init_rfcsr_3593(struc
+ 	/* TODO: enable stream mode support */
  }
  
 +static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
@@ -202,9 +202,9 @@
  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
  {
  	rt2800_rf_init_calibration(rt2x00dev, 2);
-@@ -5410,6 +5511,9 @@ static void rt2800_init_rfcsr(struct rt2
- 	case RT3572:
- 		rt2800_init_rfcsr_3572(rt2x00dev);
+@@ -6655,6 +6756,9 @@ static void rt2800_init_rfcsr(struct rt2
+ 	case RT3593:
+ 		rt2800_init_rfcsr_3593(rt2x00dev);
  		break;
 +	case RT5350:
 +		rt2800_init_rfcsr_5350(rt2x00dev);
@@ -212,9 +212,9 @@
  	case RT5390:
  		rt2800_init_rfcsr_5390(rt2x00dev);
  		break;
-@@ -5621,6 +5725,12 @@ static int rt2800_validate_eeprom(struct
+@@ -6894,6 +6998,12 @@ static int rt2800_validate_eeprom(struct
  		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
- 		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+ 		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
  		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
 +	} else if (rt2x00_rt(rt2x00dev, RT5350)) {
 +		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 1);
@@ -225,16 +225,16 @@
  	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
  		   rt2x00_rt(rt2x00dev, RT2872)) {
  		/*
-@@ -5749,6 +5859,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7027,6 +7137,8 @@ static int rt2800_init_eeprom(struct rt2
  	    rt2x00_rt(rt2x00dev, RT5390) ||
  	    rt2x00_rt(rt2x00dev, RT5392))
- 		rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+ 		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
 +	else if (rt2x00_rt(rt2x00dev, RT5350))
 +		rf = RF5350;
  	else
  		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
  
-@@ -5765,6 +5877,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7044,6 +7156,7 @@ static int rt2800_init_eeprom(struct rt2
  	case RF3290:
  	case RF3320:
  	case RF3322:
@@ -242,7 +242,7 @@
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -6264,7 +6377,8 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7610,7 +7723,8 @@ static int rt2800_probe_hw_mode(struct r
  		   rt2x00_rf(rt2x00dev, RF5392)) {
  		spec->num_channels = 14;
  		spec->channels = rf_vals_3x;
@@ -252,18 +252,18 @@
  		spec->num_channels = 14;
  		if (spec->clk_is_20mhz)
  			spec->channels = rf_vals_xtal20mhz_3x;
-@@ -6365,6 +6479,7 @@ static int rt2800_probe_hw_mode(struct r
- 	case RF3320:
+@@ -7735,6 +7849,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF3052:
+ 	case RF3053:
  	case RF3290:
 +	case RF5350:
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -6402,6 +6517,7 @@ static int rt2800_probe_rt(struct rt2x00
- 	case RT3352:
+@@ -7773,6 +7888,7 @@ static int rt2800_probe_rt(struct rt2x00
  	case RT3390:
  	case RT3572:
+ 	case RT3593:
 +	case RT5350:
  	case RT5390:
  	case RT5392:

+ 1 - 1
package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch

@@ -8,7 +8,7 @@
  
  #include "rt2x00.h"
  #include "rt2800lib.h"
-@@ -5966,6 +5967,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7245,6 +7246,17 @@ static int rt2800_init_eeprom(struct rt2
  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);