rt2x00: mt7620: differentiate based on SoC's CHIP_VER
authorDaniel Golle <daniel@makrotopia.org>
Sun, 5 Feb 2017 16:55:53 +0000 (17:55 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Fri, 9 Oct 2020 00:50:30 +0000 (01:50 +0100)
The vendor driver does things differently based on what it finds in the
SoC's CHIP_VER register, which should tell whether this is MT7620N or
MT7620A (PKG) and probably also the revision (VER) and most likely
also something about the silicon implementer (ECO).
Introduce codepaths just like the ones in the vendor driver to handle
the different chips properly.

Some of those paths are most likely dead code and left-overs from FPGA
versions or early prototypes of the chip. It'd thus be great if people
can post their kernel logs, at least the line telling the chip version
and eco, so we know what's actually out there in the wild -- all I
could find is
[ 0.000000] SoC Type: Ralink MT7620A ver:2 eco:6
and
[ 0.000000] SoC Type: Ralink MT7620N ver:2 eco:6
which would make things easier, as then we really just need to know
whether it's MT7620N or MT7620A and not care about FPGA or prototypes
with ver <= 1 and eco <= 2.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
package/kernel/mac80211/patches/rt2x00/990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/rt2x00/990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch b/package/kernel/mac80211/patches/rt2x00/990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch
new file mode 100644 (file)
index 0000000..76114fe
--- /dev/null
@@ -0,0 +1,139 @@
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -78,6 +78,9 @@ struct rt2800_ops {
+       int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
+       __le32 *(*drv_get_txwi)(struct queue_entry *entry);
+       unsigned int (*drv_get_dma_done)(struct data_queue *queue);
++      int (*hw_get_chippkg)(void);
++      int (*hw_get_chipver)(void);
++      int (*hw_get_chipeco)(void);
+ };
+ static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev,
+@@ -195,6 +198,27 @@ static inline unsigned int rt2800_drv_ge
+       return rt2800ops->drv_get_dma_done(queue);
+ }
++static inline int rt2800_hw_get_chippkg(struct rt2x00_dev *rt2x00dev)
++{
++      const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
++
++      return rt2800ops->hw_get_chippkg();
++}
++
++static inline int rt2800_hw_get_chipver(struct rt2x00_dev *rt2x00dev)
++{
++      const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
++
++      return rt2800ops->hw_get_chipver();
++}
++
++static inline int rt2800_hw_get_chipeco(struct rt2x00_dev *rt2x00dev)
++{
++      const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
++
++      return rt2800ops->hw_get_chipeco();
++}
++
+ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
+                       const u8 command, const u8 token,
+                       const u8 arg0, const u8 arg1);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+@@ -286,6 +286,10 @@ static int rt2800pci_read_eeprom(struct
+       return retval;
+ }
++static int rt2800pci_get_chippkg(void) { return 0; }
++static int rt2800pci_get_chipver(void) { return 0; }
++static int rt2800pci_get_chipeco(void) { return 0; }
++
+ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
+       .tx                     = rt2x00mac_tx,
+       .start                  = rt2x00mac_start,
+@@ -328,6 +332,9 @@ static const struct rt2800_ops rt2800pci
+       .drv_init_registers     = rt2800mmio_init_registers,
+       .drv_get_txwi           = rt2800mmio_get_txwi,
+       .drv_get_dma_done       = rt2800mmio_get_dma_done,
++      .hw_get_chippkg         = rt2800pci_get_chippkg,
++      .hw_get_chipver         = rt2800pci_get_chipver,
++      .hw_get_chipeco         = rt2800pci_get_chipeco,
+ };
+ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+@@ -27,6 +27,12 @@
+ #include "rt2800lib.h"
+ #include "rt2800mmio.h"
++/* Needed to probe CHIP_VER register on MT7620 */
++#ifdef CONFIG_SOC_MT7620
++#include <asm/mach-ralink/ralink_regs.h>
++#include <asm/mach-ralink/mt7620.h>
++#endif
++
+ /* Allow hardware encryption to be disabled. */
+ static bool modparam_nohwcrypt;
+ module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
+@@ -118,6 +124,27 @@ static int rt2800soc_write_firmware(stru
+       return 0;
+ }
++#ifdef CONFIG_SOC_MT7620
++static int rt2800soc_get_chippkg(void)
++{
++      return mt7620_get_pkg();
++}
++
++static int rt2800soc_get_chipver(void)
++{
++      return mt7620_get_chipver();
++}
++
++static int rt2800soc_get_chipeco(void)
++{
++      return mt7620_get_eco();
++}
++#else
++static int rt2800soc_get_chippkg(void) { return 0; }
++static int rt2800soc_get_chipver(void) { return 0; }
++static int rt2800soc_get_chipeco(void) { return 0; }
++#endif
++
+ static const struct ieee80211_ops rt2800soc_mac80211_ops = {
+       .tx                     = rt2x00mac_tx,
+       .start                  = rt2x00mac_start,
+@@ -159,6 +186,9 @@ static const struct rt2800_ops rt2800soc
+       .drv_init_registers     = rt2800mmio_init_registers,
+       .drv_get_txwi           = rt2800mmio_get_txwi,
+       .drv_get_dma_done       = rt2800mmio_get_dma_done,
++      .hw_get_chippkg         = rt2800soc_get_chippkg,
++      .hw_get_chipver         = rt2800soc_get_chipver,
++      .hw_get_chipeco         = rt2800soc_get_chipeco,
+ };
+ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+@@ -628,6 +628,10 @@ static int rt2800usb_probe_hw(struct rt2
+       return 0;
+ }
++static int rt2800usb_get_chippkg(void) { return 0; }
++static int rt2800usb_get_chipver(void) { return 0; }
++static int rt2800usb_get_chipeco(void) { return 0; }
++
+ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
+       .tx                     = rt2x00mac_tx,
+       .start                  = rt2x00mac_start,
+@@ -671,6 +675,9 @@ static const struct rt2800_ops rt2800usb
+       .drv_init_registers     = rt2800usb_init_registers,
+       .drv_get_txwi           = rt2800usb_get_txwi,
+       .drv_get_dma_done       = rt2800usb_get_dma_done,
++      .hw_get_chippkg         = rt2800usb_get_chippkg,
++      .hw_get_chipver         = rt2800usb_get_chipver,
++      .hw_get_chipeco         = rt2800usb_get_chipeco,
+ };
+ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
diff --git a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch
new file mode 100644 (file)
index 0000000..3de00b2
--- /dev/null
@@ -0,0 +1,408 @@
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -1042,6 +1042,11 @@
+ #define MIMO_PS_CFG_RX_STBY_POL               FIELD32(0x00000010)
+ #define MIMO_PS_CFG_RX_RX_STBY0               FIELD32(0x00000020)
++#define BB_PA_MODE_CFG0                       0x1214
++#define BB_PA_MODE_CFG1                       0x1218
++#define RF_PA_MODE_CFG0                       0x121C
++#define RF_PA_MODE_CFG1                       0x1220
++
+ /*
+  * EDCA_AC0_CFG:
+  */
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3685,14 +3685,16 @@ static void rt2800_config_channel_rf7620
+       rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4);
+       rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
+-      /* Default: XO=20MHz , SDM mode */
+-      rfcsr = rt2800_rfcsr_read(rt2x00dev, 16);
+-      rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
+-      rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
+-
+-      rfcsr = rt2800_rfcsr_read(rt2x00dev, 21);
+-      rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
+-      rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
++              /* Default: XO=20MHz , SDM mode */
++              rfcsr = rt2800_rfcsr_read(rt2x00dev, 16);
++              rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
++              rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
++
++              rfcsr = rt2800_rfcsr_read(rt2x00dev, 21);
++              rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
++              rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
++      }
+       rfcsr = rt2800_rfcsr_read(rt2x00dev, 1);
+       rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620,
+@@ -3726,18 +3728,23 @@ static void rt2800_config_channel_rf7620
+               rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20);
+       }
+-      if (conf_is_ht40(conf)) {
+-              rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
+-              rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
+-      } else {
+-              rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
+-              rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
++              if (conf_is_ht40(conf)) {
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
++              } else {
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
++              }
+       }
+-      rfcsr = rt2800_rfcsr_read(rt2x00dev, 28);
+-      rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
+-                        conf_is_ht40(conf) && (rf->channel == 11));
+-      rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
++          rt2800_hw_get_chipeco(rt2x00dev) == 2) {
++              rfcsr = rt2800_rfcsr_read(rt2x00dev, 28);
++              rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
++                                conf_is_ht40(conf) && (rf->channel == 11));
++              rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
++      }
+       if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) {
+               if (conf_is_ht40(conf)) {
+@@ -3837,25 +3844,29 @@ static void rt2800_config_alc(struct rt2
+       if (i == 10000)
+               rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
+-      if (chan->center_freq > 2457) {
+-              bbp = rt2800_bbp_read(rt2x00dev, 30);
+-              bbp = 0x40;
+-              rt2800_bbp_write(rt2x00dev, 30, bbp);
+-              rt2800_rfcsr_write(rt2x00dev, 39, 0);
+-              if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
+-                      rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
+-              else
+-                      rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
+-      } else {
+-              bbp = rt2800_bbp_read(rt2x00dev, 30);
+-              bbp = 0x1f;
+-              rt2800_bbp_write(rt2x00dev, 30, bbp);
+-              rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
+-              if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
+-                      rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
+-              else
+-                      rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
++          rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
++              if (chan->center_freq > 2457) {
++                      bbp = rt2800_bbp_read(rt2x00dev, 30);
++                      bbp = 0x40;
++                      rt2800_bbp_write(rt2x00dev, 30, bbp);
++                      rt2800_rfcsr_write(rt2x00dev, 39, 0);
++                      if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
++                              rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
++                      else
++                              rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
++              } else {
++                      bbp = rt2800_bbp_read(rt2x00dev, 30);
++                      bbp = 0x1f;
++                      rt2800_bbp_write(rt2x00dev, 30, bbp);
++                      rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++                      if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
++                              rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
++                      else
++                              rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
++              }
+       }
++
+       rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
+       rt2800_vco_calibration(rt2x00dev);
+@@ -5887,18 +5898,33 @@ static int rt2800_init_registers(struct
+       } else if (rt2x00_rt(rt2x00dev, RT5350)) {
+               rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+       } else if (rt2x00_rt(rt2x00dev, RT6352)) {
+-              rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
+-              rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
+-              rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+-              rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
+-              rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
+-              rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
+-              rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
+-              rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C);
+-              rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
+-                                    0x3630363A);
+-              rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
+-                                    0x3630363A);
++              if (rt2800_hw_get_chipver(rt2x00dev) <= 1) {
++                      rt2800_register_write(rt2x00dev, TX_ALC_VGA3,
++                                            0x00000000);
++                      rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG0,
++                                            0x000055FF);
++                      rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG1,
++                                            0x00550055);
++                      rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG0,
++                                            0x000055FF);
++                      rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG1,
++                                            0x00550055);
++              } else {
++                      rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
++                      rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
++                      rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
++                      rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
++                      rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
++                      rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
++                      rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
++                                            0x6C6C666C);
++                      rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
++                                            0x6C6C666C);
++                      rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
++                                            0x3630363A);
++                      rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
++                                            0x3630363A);
++              }
+               reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1);
+               rt2x00_set_field32(&reg, TX_ALC_CFG_1_ROS_BUSY_EN, 0);
+               rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
+@@ -7042,14 +7068,16 @@ static void rt2800_init_bbp_6352(struct
+       rt2800_bbp_write(rt2x00dev, 188, 0x00);
+       rt2800_bbp_write(rt2x00dev, 189, 0x00);
+-      rt2800_bbp_write(rt2x00dev, 91, 0x06);
+-      rt2800_bbp_write(rt2x00dev, 92, 0x04);
+-      rt2800_bbp_write(rt2x00dev, 93, 0x54);
+-      rt2800_bbp_write(rt2x00dev, 99, 0x50);
+-      rt2800_bbp_write(rt2x00dev, 148, 0x84);
+-      rt2800_bbp_write(rt2x00dev, 167, 0x80);
+-      rt2800_bbp_write(rt2x00dev, 178, 0xFF);
+-      rt2800_bbp_write(rt2x00dev, 106, 0x13);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
++              rt2800_bbp_write(rt2x00dev, 91, 0x06);
++              rt2800_bbp_write(rt2x00dev, 92, 0x04);
++              rt2800_bbp_write(rt2x00dev, 93, 0x54);
++              rt2800_bbp_write(rt2x00dev, 99, 0x50);
++              rt2800_bbp_write(rt2x00dev, 148, 0x84);
++              rt2800_bbp_write(rt2x00dev, 167, 0x80);
++              rt2800_bbp_write(rt2x00dev, 178, 0xFF);
++              rt2800_bbp_write(rt2x00dev, 106, 0x13);
++      }
+       /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
+       rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
+@@ -10388,31 +10416,36 @@ static void rt2800_init_rfcsr_6352(struc
+       rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
+       rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
+-      rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
+-      if (rt2800_clk_is_20mhz(rt2x00dev))
+-              rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
+-      else
+-              rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
+-      rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
+-      rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
+-      rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
+-      rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
+-      rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
+-      rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
+-      rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
+-      rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+-      rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
+-      rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+-      rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
+-      rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
+-      rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+-      rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
+-      rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
+-      rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
+-
+-      rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
+-      rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
+-      rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
++              rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
++              if (rt2800_clk_is_20mhz(rt2x00dev))
++                      rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
++              else
++                      rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
++              rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
++              rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
++              rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
++              rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
++              rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
++              rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
++              rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
++              rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
++              rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
++              rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
++              rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
++              rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
++              rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
++              rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
++              rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
++              rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
++      }
++
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
++          rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
++              rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
++              rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
++              rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++      }
+       /* Initialize RF channel register to default value */
+       rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
+@@ -10478,63 +10511,71 @@ static void rt2800_init_rfcsr_6352(struc
+       rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
+-      rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67);
+-      rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
+-      rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27);
+-      rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
+-
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
+-
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
+-
+-      /* Initialize RF channel register for DRQFN */
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
+-      rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
++              rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67);
++              rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
++              rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27);
++              rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
++      }
++
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
++          rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
++
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
++      }
++
++      if (rt2800_hw_get_chippkg(rt2x00dev) == 0 &&
++          rt2800_hw_get_chipver(rt2x00dev) == 1) {
++              /* Initialize RF channel register for DRQFN */
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
++      }
+       /* Initialize RF DC calibration register to default value */
+       rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
+@@ -10597,12 +10638,17 @@ static void rt2800_init_rfcsr_6352(struc
+       rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
+       rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
+-      rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
+-      rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
+-      rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
++              rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
++              rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
++              rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
++      }
+-      rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
+-      rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
++      if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
++          rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
++              rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
++              rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
++      }
+       rt2800_r_calibration(rt2x00dev);
+       rt2800_rf_self_txdc_cal(rt2x00dev);