mac80211: clean and submit a bunch of rt2x00 patches
authorDaniel Golle <daniel@makrotopia.org>
Fri, 16 Sep 2022 23:33:30 +0000 (00:33 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Fri, 16 Sep 2022 23:44:08 +0000 (00:44 +0100)
Clean and submit patches, mostly related to MT7620 to linux-wireless
mailing list:
https://patchwork.kernel.org/project/linux-wireless/list/?series=677770

Replace local patches with now submitted versions.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
22 files changed:
package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch
package/kernel/mac80211/patches/rt2x00/612-rt2x00-add-throughput-LED-trigger.patch
package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch
package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-RF-self-TXDC-calibration.patch
package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch
package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-RXDCOC-calibration.patch
package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-RXIQ-calibration.patch
package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch [deleted file]
package/kernel/mac80211/patches/rt2x00/986-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/987-rt2x00-add-TX-LOFT-calibration.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/988-rt2x00-move-helper-functions-up-in-file.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/989-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch [deleted file]
package/kernel/mac80211/patches/rt2x00/990-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT762.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch [deleted file]
package/kernel/mac80211/patches/rt2x00/991-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/992-rt2x00-more-fixes.patch [deleted file]
package/kernel/mac80211/patches/rt2x00/992-rt2x00-set-SoC-wmac-clock-register.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/993-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch [new file with mode: 0644]

index 96eeb37dc603000bb2e25c4a24b5fcb10c42b99f..df4aab0d9586a1e409846393f5e490cc12263ab7 100644 (file)
@@ -1,26 +1,21 @@
-From patchwork Thu Dec 27 14:05:26 2018
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: Tom Psyborg <pozega.tomislav@gmail.com>
-X-Patchwork-Id: 10743707
-X-Patchwork-Delegate: kvalo@adurom.com
-From: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com>
-To: linux-wireless@vger.kernel.org
-Cc: kvalo@codeaurora.org, hauke@hauke-m.de, nbd@nbd.name,
-        john@phrozen.org, sgruszka@redhat.com, daniel@makrotopia.org
-Subject: [PATCH 2/2] rt2x00: define RF5592 in init_eeprom routine
+From 15eed6b853b7e06f08632ef3cbe6cc42ac3eb858 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
 Date: Thu, 27 Dec 2018 15:05:26 +0100
-Message-Id: <1545919526-4074-2-git-send-email-pozega.tomislav@gmail.com>
-X-Mailer: git-send-email 1.7.0.4
-In-Reply-To: <1545919526-4074-1-git-send-email-pozega.tomislav@gmail.com>
-References: <1545919526-4074-1-git-send-email-pozega.tomislav@gmail.com>
+Subject: [PATCH 01/16] rt2x00: define RF5592 in init_eeprom routine
 MIME-Version: 1.0
-Sender: linux-wireless-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <linux-wireless.vger.kernel.org>
-X-Mailing-List: linux-wireless@vger.kernel.org
-X-Virus-Scanned: ClamAV using ClamSMTP
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
 
 This patch fixes following crash on Linksys EA2750 during 5GHz wifi
 init:
@@ -35,8 +30,8 @@ init:
 
 Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 ---
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++
+ 1 file changed, 2 insertions(+)
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index f27873acc0dda20934c9e25bfbf9289930467a02..c9cada6dbd51e40b161d8cc1a197f329549b94fe 100644 (file)
@@ -1,16 +1,28 @@
-From: David Bauer <mail@david-bauer.net>
+From 208be6e22eba13408a0a3eb4c02256bc9ddfaf48 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
 Date: Mon, 16 Dec 2019 20:47:06 +0100
-Subject: [PATCH] rt2x00: add throughput LED trigger
+Subject: [PATCH 02/16] rt2x00: add throughput LED trigger
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: David Bauer <mail@david-bauer.net>
 
 This adds a (currently missing) throughput LED trigger for the rt2x00
 driver. Previously, LED triggers had to be assigned to the netdev, which
 was limited to a single VAP.
 
-Signed-off-by: David Bauer <mail@david-bauer.net>
 Tested-by: Christoph Krapp <achterin@googlemail.com>
+Signed-off-by: David Bauer <mail@david-bauer.net>
 ---
- drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 1+++++++++++++++++
- 1 file changed, 17 insertions(+)
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -34,13 +46,14 @@ Tested-by: Christoph Krapp <achterin@googlemail.com>
  static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
  {
        struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -1206,6 +1219,10 @@ static int rt2x00lib_probe_hw(struct rt2
+@@ -1206,6 +1219,11 @@ static int rt2x00lib_probe_hw(struct rt2
  
  #undef RT2X00_TASKLET_INIT
  
 +      ieee80211_create_tpt_led_trigger(rt2x00dev->hw,
-+              IEEE80211_TPT_LEDTRIG_FL_RADIO, rt2x00_tpt_blink,
-+              ARRAY_SIZE(rt2x00_tpt_blink));
++                                       IEEE80211_TPT_LEDTRIG_FL_RADIO,
++                                       rt2x00_tpt_blink,
++                                       ARRAY_SIZE(rt2x00_tpt_blink));
 +
        /*
         * Register HW.
index 8814c0253232ec9858f11f68f22edaf3c916761e..fe023cf77a4b8fcdb40096166e6d43bb785a9533 100644 (file)
@@ -1,22 +1,29 @@
-From 9782a7f7488443568fa4d6088b73c9aff7eb8510 Mon Sep 17 00:00:00 2001
+From 8dcdb02e3ad5f3d384c071e0a36670bb342bab35 Mon Sep 17 00:00:00 2001
 From: Daniel Golle <daniel@makrotopia.org>
 Date: Wed, 19 Apr 2017 16:14:53 +0200
-Subject: [PATCH] rt2x00: add support for external PA on MT7620
-To: Stanislaw Gruszka <sgruszka@redhat.com>
-Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
-    linux-wireless@vger.kernel.org,
-    Kalle Valo <kvalo@codeaurora.org>
-Content-Type: text/plain; charset="UTF-8"
-Content-Transfer-Encoding: quoted-printable
+Subject: [PATCH 03/16] rt2x00: add support for external PA on MT7620
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
 
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
-[pozega.tomislav@gmail.com: use chanreg and dccal helpers.]
+Implement support for external PA connected to MT7620A.
 
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+[pozega.tomislav@gmail.com: use chanreg and dccal helpers.]
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 ---
- drivers/net/wireless/ralink/rt2x00/rt2800.h    |  1 +
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++-
- 2 files changed, 70 insertions(+), 1 deletion(-)
+ drivers/net/wireless/ralink/rt2x00/rt2800.h   |  1 +
.../net/wireless/ralink/rt2x00/rt2800lib.c    | 52 ++++++++++++++++++-
+ 2 files changed, 52 insertions(+), 1 deletion(-)
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
@@ -24,21 +31,19 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
  #define EEPROM_NIC_CONF2_RX_STREAM    FIELD16(0x000f)
  #define EEPROM_NIC_CONF2_TX_STREAM    FIELD16(0x00f0)
  #define EEPROM_NIC_CONF2_CRYSTAL      FIELD16(0x0600)
-+#define EEPROM_NIC_CONF2_EXTERNAL_PA  FIELD16(0xc000)
++#define EEPROM_NIC_CONF2_EXTERNAL_PA  FIELD16(0x8000)
  
  /*
   * EEPROM LNA
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4369,6 +4369,45 @@ static void rt2800_config_channel(struct
+@@ -4369,6 +4369,43 @@ static void rt2800_config_channel(struct
                rt2800_iq_calibrate(rt2x00dev, rf->channel);
        }
  
 +      if (rt2x00_rt(rt2x00dev, RT6352)) {
 +              if (test_bit(CAPABILITY_EXTERNAL_PA_TX0,
 +                           &rt2x00dev->cap_flags)) {
-+                      rt2x00_warn(rt2x00dev, "Using incomplete support for " \
-+                                             "external PA\n");
 +                      reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
 +                      reg |= 0x00000101;
 +                      rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
@@ -76,7 +81,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
        bbp = rt2800_bbp_read(rt2x00dev, 4);
        rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
        rt2800_bbp_write(rt2x00dev, 4, bbp);
-@@ -9578,7 +9617,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9578,7 +9615,8 @@ static int rt2800_init_eeprom(struct rt2
         */
        eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
  
@@ -86,19 +91,19 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
                if (rt2x00_get_field16(eeprom,
                    EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
                    __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
-@@ -9589,6 +9629,18 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9589,6 +9627,18 @@ static int rt2800_init_eeprom(struct rt2
                              &rt2x00dev->cap_flags);
        }
  
 +      eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF2);
 +
 +      if (rt2x00_rt(rt2x00dev, RT6352) && eeprom != 0 && eeprom != 0xffff) {
-+              if (rt2x00_get_field16(eeprom,
-+                  EEPROM_NIC_CONF2_EXTERNAL_PA)) {
-+                  __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
-+                            &rt2x00dev->cap_flags);
-+                  __set_bit(CAPABILITY_EXTERNAL_PA_TX1,
-+                            &rt2x00dev->cap_flags);
++              if (!rt2x00_get_field16(eeprom,
++                                      EEPROM_NIC_CONF2_EXTERNAL_PA)) {
++                      __clear_bit(CAPABILITY_EXTERNAL_PA_TX0,
++                                  &rt2x00dev->cap_flags);
++                      __clear_bit(CAPABILITY_EXTERNAL_PA_TX1,
++                                  &rt2x00dev->cap_flags);
 +              }
 +      }
 +
index b74bea20202f64cfa41733b43711720da8234941..ed8a737a4c6bc439bccd6c1e7e09ba4879a7462f 100644 (file)
@@ -1,20 +1,32 @@
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+From 21f2acf0f9e9da35fbdb96ee0aea97b02472030b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
 Date: Mon, 8 Jan 2018 13:42:27 +0100
-Subject: [PATCH] rt2x00: add RF self TXDC calibration
+Subject: [PATCH 04/16] rt2x00: add RF self TXDC calibration for MT7620
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
 
 Add TX self calibration based on mtk driver.
 
 Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 ---
- .../net/wireless/ralink/rt2x00/rt2800lib.c    | 51 +++++++++++++++++++
- 1 file changed, 51 insertions(+)
+ .../net/wireless/ralink/rt2x00/rt2800lib.c    | 48 +++++++++++++++++++
+ 1 file changed, 48 insertions(+)
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8438,6 +8438,56 @@ static void rt2800_init_rfcsr_5592(struc
+@@ -8436,6 +8436,53 @@ static void rt2800_init_rfcsr_5592(struc
        rt2800_led_open_drain_enable(rt2x00dev);
  }
  
@@ -24,7 +36,6 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      u32 mac0518, mac051c, mac0528, mac052c;
 +      u8 i;
 +
-+      rt2x00_info(rt2x00dev, "RF Tx self calibration start\n");
 +      mac0518 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
 +      mac051c = rt2800_register_read(rt2x00dev, RF_BYPASS0);
 +      mac0528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
@@ -42,18 +53,18 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +
 +      rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, 0x4);
 +      for (i = 0; i < 100; i = i + 1) {
-+              udelay(50);
++              usleep_range(50, 100);
 +              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
-+              if((rfvalue & 0x04) != 0x4)
++              if ((rfvalue & 0x04) != 0x4)
 +                      break;
 +      }
 +      rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rfb5r1_org);
 +
 +      rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, 0x4);
 +      for (i = 0; i < 100; i = i + 1) {
-+              udelay(50);
++              usleep_range(50, 100);
 +              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
-+              if((rfvalue & 0x04) != 0x4)
++              if ((rfvalue & 0x04) != 0x4)
 +                      break;
 +      }
 +      rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, rfb7r1_org);
@@ -64,14 +75,12 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      rt2800_register_write(rt2x00dev, RF_BYPASS0, mac051c);
 +      rt2800_register_write(rt2x00dev, RF_CONTROL2, mac0528);
 +      rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c);
-+
-+      rt2x00_info(rt2x00dev, "RF Tx self calibration end\n");
 +}
 +
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9045,6 +9095,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9043,6 +9090,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
        rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
  
index 04ea802117de48080504a28135e5bb60d1c770bc..569b1083e5bff3631e90ea2284d251f0857b3f86 100644 (file)
@@ -1,9 +1,21 @@
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+From b75efecd6473e6a044d214571c17cad8ae88ed42 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
 Date: Mon, 8 Jan 2018 13:42:58 +0100
-Subject: [PATCH] rt2x00: add r calibration
+Subject: [PATCH 05/16] rt2x00: add r calibration for MT7620
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
 
 Add r calibration code as found in mtk driver.
 
@@ -14,15 +26,15 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8488,6 +8488,155 @@ static void rt2800_rf_self_txdc_cal(stru
-       rt2x00_info(rt2x00dev, "RF Tx self calibration end\n");
+@@ -8483,6 +8483,155 @@ static void rt2800_rf_self_txdc_cal(stru
+       rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c);
  }
  
 +static int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2)
 +{
-+      int calcode;
-+      calcode = ((d2 - d1) * 1000) / 43;
-+      if ((calcode%10) >= 5)
++      int calcode = ((d2 - d1) * 1000) / 43;
++
++      if ((calcode % 10) >= 5)
 +              calcode += 10;
 +      calcode = (calcode / 10);
 +
@@ -70,7 +82,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      for (i = 0; i < 10000; i++) {
 +              macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
 +              if (macstatus & 0x1)
-+                      udelay(50);
++                      usleep_range(50, 100);
 +              else
 +                      break;
 +      }
@@ -85,7 +97,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      for (i = 0; i < 10000; i++) {
 +              macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
 +              if (macstatus & 0x2)
-+                      udelay(50);
++                      usleep_range(50, 100);
 +              else
 +                      break;
 +              }
@@ -112,7 +124,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +
 +      rt2800_bbp_write(rt2x00dev, 47, 0x04);
 +      rt2800_bbp_write(rt2x00dev, 22, 0x80);
-+      udelay(100);
++      usleep_range(100, 200);
 +      bytevalue = rt2800_bbp_read(rt2x00dev, 49);
 +      if (bytevalue > 128)
 +              d1 = bytevalue - 256;
@@ -122,7 +134,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x01);
 +
 +      rt2800_bbp_write(rt2x00dev, 22, 0x80);
-+      udelay(100);
++      usleep_range(100, 200);
 +      bytevalue = rt2800_bbp_read(rt2x00dev, 49);
 +      if (bytevalue > 128)
 +              d2 = bytevalue - 256;
@@ -170,7 +182,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9095,6 +9244,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9090,6 +9239,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
        rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
  
index 821af87ec18f27077946b0d0f1e1128ba9f55a0f..fa732c97a6132f2590d983ad8a6463e2cebd068a 100644 (file)
@@ -1,12 +1,26 @@
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+From 865823b63f608ac024d326a465ba8fc1a28868cd Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
 Date: Mon, 8 Jan 2018 13:43:37 +0100
-Subject: [PATCH] rt2x00: add RXDCOC calibration
+Subject: [PATCH 06/16] rt2x00: add RXDCOC calibration for MT7620
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
 
 Add RXDCOC calibration code from mtk driver.
 
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+[fixed typo reported by Serge Vasilugin <vasilugin@yandex.ru>]
 Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 ---
  .../net/wireless/ralink/rt2x00/rt2800lib.c    | 65 +++++++++++++++++++
@@ -14,7 +28,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8637,6 +8637,70 @@ static void rt2800_r_calibration(struct
+@@ -8632,6 +8632,70 @@ static void rt2800_r_calibration(struct
        rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
  }
  
@@ -41,12 +55,12 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      for (i = 0; i < 10000; i++) {
 +              macvalue1 = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
 +              if (macvalue1 & 0x1)
-+                      udelay(50);
++                      usleep_range(50, 100);
 +              else
 +                      break;
 +      }
 +
-+      saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0);
++      saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
 +      saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
 +      saverfb5r4 = saverfb5r4 & (~0x40);
 +      saverfb7r4 = saverfb7r4 & (~0x40);
@@ -63,9 +77,9 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +
 +      for (i = 0; i < 10000; i++) {
 +              bbpreg = rt2800_bbp_read(rt2x00dev, 159);
-+              if ((bbpreg & 0x40)==0)
++              if ((bbpreg & 0x40) == 0)
 +                      break;
-+              udelay(50);
++              usleep_range(50, 100);
 +      }
 +
 +      bbpreg = rt2800_bbp_read(rt2x00dev, 159);
@@ -85,7 +99,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9246,6 +9310,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9241,6 +9305,7 @@ static void rt2800_init_rfcsr_6352(struc
  
        rt2800_r_calibration(rt2x00dev);
        rt2800_rf_self_txdc_cal(rt2x00dev);
index 1c07cc75203b13e74572512cec34c81e1fcb91ef..59dbd1f506f9f252cafa6eedc9f8f58aaecda1da 100644 (file)
@@ -1,32 +1,46 @@
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+From 38b78ba60f6759968b19fe183a344a8612fef694 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
 Date: Mon, 8 Jan 2018 13:43:56 +0100
-Subject: [PATCH] rt2x00: add RXIQ calibration
+Subject: [PATCH 07/16] rt2x00: add RXIQ calibration for MT7620
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
 
 Add RXIQ calibration found in mtk driver. With old openwrt builds this
 gets us ~8Mbps more of RX bandwidth (test with iPA/eLNA layout).
 
 Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 ---
- .../net/wireless/ralink/rt2x00/rt2800lib.c    | 379 ++++++++++++++++++
- 1 file changed, 379 insertions(+)
+ .../net/wireless/ralink/rt2x00/rt2800lib.c    | 384 ++++++++++++++++++
+ 1 file changed, 384 insertions(+)
 
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8701,6 +8701,384 @@ static void rt2800_rxdcoc_calibration(st
+@@ -8696,6 +8696,389 @@ static void rt2800_rxdcoc_calibration(st
        rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
  }
  
-+static u32 rt2800_do_sqrt_accumulation(u32 si) {
++static u32 rt2800_do_sqrt_accumulation(u32 si)
++{
 +      u32 root, root_pre, bit;
 +      char i;
++
 +      bit = 1 << 15;
 +      root = 0;
 +      for (i = 15; i >= 0; i = i - 1) {
 +              root_pre = root + bit;
-+              if ((root_pre*root_pre) <= si)
++              if ((root_pre * root_pre) <= si)
 +                      root = root_pre;
 +              bit = bit >> 1;
 +      }
@@ -34,7 +48,8 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      return root;
 +}
 +
-+static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev) {
++static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev)
++{
 +      u8 rfb0r1, rfb0r2, rfb0r42;
 +      u8 rfb4r0, rfb4r19;
 +      u8 rfb5r3, rfb5r4, rfb5r17, rfb5r18, rfb5r19, rfb5r20;
@@ -77,7 +92,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +      for (i = 0; i < 10000; i++) {
 +              macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
 +              if (macstatus & 0x3)
-+                      udelay(50);
++                      usleep_range(50, 100);
 +              else
 +                      break;
 +      }
@@ -180,7 +195,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
 +                      udelay(1);
 +
-+                      bbpval = bbp1 & (~ 0x18);
++                      bbpval = bbp1 & (~0x18);
 +                      bbpval = bbpval | 0x00;
 +                      rt2800_bbp_write(rt2x00dev, 1, bbpval);
 +
@@ -199,13 +214,13 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006);
 +                      udelay(1);
 +
-+                      bbpval = bbp1 & (~ 0x18);
++                      bbpval = bbp1 & (~0x18);
 +                      bbpval = bbpval | 0x08;
 +                      rt2800_bbp_write(rt2x00dev, 1, bbpval);
 +
 +                      rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x01);
 +              }
-+              udelay(500);
++              usleep_range(500, 1500);
 +
 +              vga_idx = 0;
 +                      while (vga_idx < 11) {
@@ -217,7 +232,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +                              for (i = 0; i < 10000; i++) {
 +                                      bbpval = rt2800_bbp_read(rt2x00dev, 159);
 +                                      if ((bbpval & 0xff) == 0x93)
-+                                              udelay(50);
++                                              usleep_range(50, 100);
 +                                      else
 +                                              break;
 +                                      }
@@ -247,7 +262,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +                                      value = rt2800_bbp_read(rt2x00dev, 159);
 +                                      bbptemp = bbptemp + value;
 +
-+                                      if ((i < 2) && (bbptemp & 0x800000))
++                                      if (i < 2 && (bbptemp & 0x800000))
 +                                              result = (bbptemp & 0xffffff) - 0x1000000;
 +                                      else if (i == 4)
 +                                              result = bbptemp;
@@ -255,21 +270,23 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +                                              result = bbptemp;
 +
 +                                      if (i == 0)
-+                                              mi = result/4096;
++                                              mi = result / 4096;
 +                                      else if (i == 1)
-+                                              mq = result/4096;
++                                              mq = result / 4096;
 +                                      else if (i == 2)
-+                                              si = bbptemp/4096;
++                                              si = bbptemp / 4096;
 +                                      else if (i == 3)
-+                                              sq = bbptemp/4096;
++                                              sq = bbptemp / 4096;
 +                                      else
-+                                              riq = result/4096;
++                                              riq = result / 4096;
 +                              }
 +
-+                              bbpval1 = si - mi*mi;
-+                              rt2x00_dbg(rt2x00dev, "RXIQ si=%d, sq=%d, riq=%d, bbpval %d, vga_idx %d", si, sq, riq, bbpval1, vga_idx);
++                              bbpval1 = si - mi * mi;
++                              rt2x00_dbg(rt2x00dev,
++                                         "RXIQ si=%d, sq=%d, riq=%d, bbpval %d, vga_idx %d",
++                                         si, sq, riq, bbpval1, vga_idx);
 +
-+                              if (bbpval1 >= (100*100))
++                              if (bbpval1 >= (100 * 100))
 +                                      break;
 +
 +                              if (bbpval1 <= 100)
@@ -292,39 +309,39 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
 +                                      vga_idx = vga_idx + 1;
 +                      }
 +
-+              sigma_i = rt2800_do_sqrt_accumulation(100*(si - mi*mi));
-+              sigma_q = rt2800_do_sqrt_accumulation(100*(sq - mq*mq));
-+              r_iq = 10*(riq-(mi*mq));
++              sigma_i = rt2800_do_sqrt_accumulation(100 * (si - mi * mi));
++              sigma_q = rt2800_do_sqrt_accumulation(100 * (sq - mq * mq));
++              r_iq = 10 * (riq - (mi * mq));
 +
 +              rt2x00_dbg(rt2x00dev, "Sigma_i=%d, Sigma_q=%d, R_iq=%d", sigma_i, sigma_q, r_iq);
 +
-+              if (((sigma_i <= 1400 ) && (sigma_i >= 1000))
-+                      && ((sigma_i - sigma_q) <= 112)
-+                      && ((sigma_i - sigma_q) >= -112)
-+                      && ((mi <= 32) && (mi >= -32))
-+                      && ((mq <= 32) && (mq >= -32))) {
-+                              r_iq = 10*(riq-(mi*mq));
-+                              rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq);
-+
-+                              g_rx = (1000 * sigma_q) / sigma_i;
-+                              g_imb = ((-2) * 128 * (1000 - g_rx)) / (1000 + g_rx);
-+                              ph_rx = (r_iq * 2292) / (sigma_i * sigma_q);
-+                              rt2x00_info(rt2x00dev, "RXIQ G_imb=%d, Ph_rx=%d\n", g_imb, ph_rx);
-+
-+                              if ((ph_rx > 20) || (ph_rx < -20)) {
-+                                      ph_rx = 0;
-+                                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-+                              }
++              if (sigma_i <= 1400 && sigma_i >= 1000 &&
++                  (sigma_i - sigma_q) <= 112 &&
++                  (sigma_i - sigma_q) >= -112 &&
++                  mi <= 32 && mi >= -32 &&
++                  mq <= 32 && mq >= -32) {
++                      r_iq = 10 * (riq - (mi * mq));
++                      rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n",
++                                 sigma_i, sigma_q, r_iq);
++
++                      g_rx = (1000 * sigma_q) / sigma_i;
++                      g_imb = ((-2) * 128 * (1000 - g_rx)) / (1000 + g_rx);
++                      ph_rx = (r_iq * 2292) / (sigma_i * sigma_q);
++
++                      if (ph_rx > 20 || ph_rx < -20) {
++                              ph_rx = 0;
++                              rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
++                      }
 +
-+                              if ((g_imb > 12) || (g_imb < -12)) {
-+                                      g_imb = 0;
-+                                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-+                              }
++                      if (g_imb > 12 || g_imb < -12) {
++                              g_imb = 0;
++                              rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
 +                      }
-+              else {
++              else {
 +                      g_imb = 0;
 +                      ph_rx = 0;
-+                      rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq);
++                      rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n",
++                                 sigma_i, sigma_q, r_iq);
 +                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
 +              }
 +
@@ -400,7 +417,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9313,6 +9691,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9308,6 +9691,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rxdcoc_calibration(rt2x00dev);
        rt2800_bw_filter_calibration(rt2x00dev, true);
        rt2800_bw_filter_calibration(rt2x00dev, false);
diff --git a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch
deleted file mode 100644 (file)
index a816aaf..0000000
+++ /dev/null
@@ -1,988 +0,0 @@
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
-Date: Thu, 11 Jan 2018 19:53:49 +0100
-Subject: [PATCH] rt2x00: add TX LOFT calibration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add TX LOFT calibration from mtk driver.
-
-Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
----
- .../net/wireless/ralink/rt2x00/rt2800lib.c    | 938 ++++++++++++++++++
- .../net/wireless/ralink/rt2x00/rt2800lib.h    |  10 +
- 2 files changed, 948 insertions(+)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -9079,6 +9079,943 @@ restore_value:
-       rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
- }
-+static void rt2800_rf_configstore(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_reg_record[][13], u8 chain)
-+{
-+      u8 rfvalue = 0;
-+
-+      if (chain == CHAIN_0) {
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
-+              rf_reg_record[CHAIN_0][0].bank = 0;
-+              rf_reg_record[CHAIN_0][0].reg = 1;
-+              rf_reg_record[CHAIN_0][0].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
-+              rf_reg_record[CHAIN_0][1].bank = 0;
-+              rf_reg_record[CHAIN_0][1].reg = 2;
-+              rf_reg_record[CHAIN_0][1].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
-+              rf_reg_record[CHAIN_0][2].bank = 0;
-+              rf_reg_record[CHAIN_0][2].reg = 35;
-+              rf_reg_record[CHAIN_0][2].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
-+              rf_reg_record[CHAIN_0][3].bank = 0;
-+              rf_reg_record[CHAIN_0][3].reg = 42;
-+              rf_reg_record[CHAIN_0][3].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
-+              rf_reg_record[CHAIN_0][4].bank = 4;
-+              rf_reg_record[CHAIN_0][4].reg = 0;
-+              rf_reg_record[CHAIN_0][4].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 2);
-+              rf_reg_record[CHAIN_0][5].bank = 4;
-+              rf_reg_record[CHAIN_0][5].reg = 2;
-+              rf_reg_record[CHAIN_0][5].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 34);
-+              rf_reg_record[CHAIN_0][6].bank = 4;
-+              rf_reg_record[CHAIN_0][6].reg = 34;
-+              rf_reg_record[CHAIN_0][6].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
-+              rf_reg_record[CHAIN_0][7].bank = 5;
-+              rf_reg_record[CHAIN_0][7].reg = 3;
-+              rf_reg_record[CHAIN_0][7].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
-+              rf_reg_record[CHAIN_0][8].bank = 5;
-+              rf_reg_record[CHAIN_0][8].reg = 4;
-+              rf_reg_record[CHAIN_0][8].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
-+              rf_reg_record[CHAIN_0][9].bank = 5;
-+              rf_reg_record[CHAIN_0][9].reg = 17;
-+              rf_reg_record[CHAIN_0][9].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
-+              rf_reg_record[CHAIN_0][10].bank = 5;
-+              rf_reg_record[CHAIN_0][10].reg = 18;
-+              rf_reg_record[CHAIN_0][10].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
-+              rf_reg_record[CHAIN_0][11].bank = 5;
-+              rf_reg_record[CHAIN_0][11].reg = 19;
-+              rf_reg_record[CHAIN_0][11].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
-+              rf_reg_record[CHAIN_0][12].bank = 5;
-+              rf_reg_record[CHAIN_0][12].reg = 20;
-+              rf_reg_record[CHAIN_0][12].value = rfvalue;
-+      } else if (chain == CHAIN_1) {
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
-+              rf_reg_record[CHAIN_1][0].bank = 0;
-+              rf_reg_record[CHAIN_1][0].reg = 1;
-+              rf_reg_record[CHAIN_1][0].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
-+              rf_reg_record[CHAIN_1][1].bank = 0;
-+              rf_reg_record[CHAIN_1][1].reg = 2;
-+              rf_reg_record[CHAIN_1][1].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
-+              rf_reg_record[CHAIN_1][2].bank = 0;
-+              rf_reg_record[CHAIN_1][2].reg = 35;
-+              rf_reg_record[CHAIN_1][2].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
-+              rf_reg_record[CHAIN_1][3].bank = 0;
-+              rf_reg_record[CHAIN_1][3].reg = 42;
-+              rf_reg_record[CHAIN_1][3].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
-+              rf_reg_record[CHAIN_1][4].bank = 6;
-+              rf_reg_record[CHAIN_1][4].reg = 0;
-+              rf_reg_record[CHAIN_1][4].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 2);
-+              rf_reg_record[CHAIN_1][5].bank = 6;
-+              rf_reg_record[CHAIN_1][5].reg = 2;
-+              rf_reg_record[CHAIN_1][5].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 34);
-+              rf_reg_record[CHAIN_1][6].bank = 6;
-+              rf_reg_record[CHAIN_1][6].reg = 34;
-+              rf_reg_record[CHAIN_1][6].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
-+              rf_reg_record[CHAIN_1][7].bank = 7;
-+              rf_reg_record[CHAIN_1][7].reg = 3;
-+              rf_reg_record[CHAIN_1][7].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
-+              rf_reg_record[CHAIN_1][8].bank = 7;
-+              rf_reg_record[CHAIN_1][8].reg = 4;
-+              rf_reg_record[CHAIN_1][8].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
-+              rf_reg_record[CHAIN_1][9].bank = 7;
-+              rf_reg_record[CHAIN_1][9].reg = 17;
-+              rf_reg_record[CHAIN_1][9].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
-+              rf_reg_record[CHAIN_1][10].bank = 7;
-+              rf_reg_record[CHAIN_1][10].reg = 18;
-+              rf_reg_record[CHAIN_1][10].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
-+              rf_reg_record[CHAIN_1][11].bank = 7;
-+              rf_reg_record[CHAIN_1][11].reg = 19;
-+              rf_reg_record[CHAIN_1][11].value = rfvalue;
-+              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
-+              rf_reg_record[CHAIN_1][12].bank = 7;
-+              rf_reg_record[CHAIN_1][12].reg = 20;
-+              rf_reg_record[CHAIN_1][12].value = rfvalue;
-+      } else {
-+              rt2x00_warn(rt2x00dev, "Unknown chain = %u\n", chain);
-+              return;
-+      }
-+
-+      return;
-+}
-+
-+static void rt2800_rf_configrecover(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_record[][13])
-+{
-+      u8 chain_index = 0, record_index = 0;
-+      u8 bank = 0, rf_register = 0, value = 0;
-+
-+      for (chain_index = 0; chain_index < 2; chain_index++) {
-+              for (record_index = 0; record_index < 13; record_index++) {
-+                      bank = rf_record[chain_index][record_index].bank;
-+                      rf_register = rf_record[chain_index][record_index].reg;
-+                      value = rf_record[chain_index][record_index].value;
-+                      rt2800_rfcsr_write_bank(rt2x00dev, bank, rf_register, value);
-+                      rt2x00_dbg(rt2x00dev, "bank: %d, rf_register: %d, value: %x\n", bank, rf_register, value);
-+              }
-+      }
-+
-+      return;
-+}
-+
-+static void rt2800_setbbptonegenerator(struct rt2x00_dev *rt2x00dev)
-+{
-+      rt2800_bbp_write(rt2x00dev, 158, 0xAA);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xAB);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x0A);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xAC);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x3F);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xAD);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x3F);
-+
-+      rt2800_bbp_write(rt2x00dev, 244, 0x40);
-+
-+      return;
-+}
-+
-+static u32 rt2800_do_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx, u8 read_neg)
-+{
-+      u32 macvalue = 0;
-+      int fftout_i = 0, fftout_q = 0;
-+      u32 ptmp=0, pint = 0;
-+      u8 bbp = 0;
-+      u8 tidxi;
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x9b);
-+
-+      bbp = 0x9b;
-+
-+      while (bbp == 0x9b) {
-+              udelay(10);
-+              bbp = rt2800_bbp_read(rt2x00dev, 159);
-+              bbp = bbp & 0xff;
-+      }
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xba);
-+      rt2800_bbp_write(rt2x00dev, 159, tidx);
-+      rt2800_bbp_write(rt2x00dev, 159, tidx);
-+      rt2800_bbp_write(rt2x00dev, 159, tidx);
-+
-+      macvalue = rt2800_register_read(rt2x00dev, 0x057C);
-+
-+      fftout_i = (macvalue >> 16);
-+      fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
-+      fftout_q = (macvalue & 0xffff);
-+      fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
-+      ptmp = (fftout_i * fftout_i);
-+      ptmp = ptmp + (fftout_q * fftout_q);
-+      pint = ptmp;
-+      rt2x00_dbg(rt2x00dev, "I = %d,  Q = %d, power = %x\n", fftout_i, fftout_q, pint);
-+      if (read_neg) {
-+              pint = pint >> 1;
-+              tidxi = 0x40 - tidx;
-+              tidxi = tidxi & 0x3f;
-+
-+              rt2800_bbp_write(rt2x00dev, 158, 0xba);
-+              rt2800_bbp_write(rt2x00dev, 159, tidxi);
-+              rt2800_bbp_write(rt2x00dev, 159, tidxi);
-+              rt2800_bbp_write(rt2x00dev, 159, tidxi);
-+
-+              macvalue = rt2800_register_read(rt2x00dev, 0x057C);
-+
-+              fftout_i = (macvalue >> 16);
-+              fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
-+              fftout_q = (macvalue & 0xffff);
-+              fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
-+              ptmp = (fftout_i * fftout_i);
-+              ptmp = ptmp + (fftout_q * fftout_q);
-+              ptmp = ptmp >> 1;
-+              pint = pint + ptmp;
-+      }
-+
-+      return pint;
-+}
-+
-+static u32 rt2800_read_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx) {
-+      u32 macvalue = 0;
-+      int fftout_i = 0, fftout_q = 0;
-+      u32 ptmp=0, pint = 0;
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xBA);
-+      rt2800_bbp_write(rt2x00dev, 159, tidx);
-+      rt2800_bbp_write(rt2x00dev, 159, tidx);
-+      rt2800_bbp_write(rt2x00dev, 159, tidx);
-+
-+      macvalue = rt2800_register_read(rt2x00dev, 0x057C);
-+
-+      fftout_i = (macvalue >> 16);
-+      fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
-+      fftout_q = (macvalue & 0xffff);
-+      fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
-+      ptmp = (fftout_i * fftout_i);
-+      ptmp = ptmp + (fftout_q * fftout_q);
-+      pint = ptmp;
-+      rt2x00_info(rt2x00dev, "I = %d,  Q = %d, power = %x\n", fftout_i, fftout_q, pint);
-+
-+      return pint;
-+}
-+
-+static void rt2800_write_dc(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc, u8 iorq, u8 dc)
-+{
-+      u8 bbp = 0;
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xb0);
-+      bbp = alc | 0x80;
-+      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+
-+      if (ch_idx == 0)
-+              bbp = (iorq == 0) ? 0xb1: 0xb2;
-+      else
-+              bbp = (iorq == 0) ? 0xb8: 0xb9;
-+
-+      rt2800_bbp_write(rt2x00dev, 158, bbp);
-+      bbp = dc;
-+      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+
-+      return;
-+}
-+
-+static void rt2800_loft_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc_idx, u8 dc_result[][RF_ALC_NUM][2])
-+{
-+      u32 p0 = 0, p1 = 0, pf = 0;
-+      char idx0 = 0, idx1 = 0;
-+      u8 idxf[] = {0x00, 0x00};
-+      u8 ibit = 0x20;
-+      u8 iorq;
-+      char bidx;
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0xb0);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x80);
-+
-+      for (bidx = 5; bidx >= 0; bidx--) {
-+              for (iorq = 0; iorq <= 1; iorq++) {
-+                      rt2x00_dbg(rt2x00dev, "\n========================================================\n");
-+
-+                      if (idxf[iorq] == 0x20) {
-+                              idx0 = 0x20;
-+                              p0 = pf;
-+                      } else {
-+                              idx0 = idxf[iorq] - ibit;
-+                              idx0 = idx0 & 0x3F;
-+                              rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx0);
-+                              p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
-+                      }
-+
-+                      idx1 = idxf[iorq] + ((bidx == 5) ? 0 : ibit);
-+                      idx1 = idx1 & 0x3F;
-+                      rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx1);
-+                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
-+
-+                      rt2x00_dbg(rt2x00dev, "alc=%u, IorQ=%u, idx_final=%2x\n", alc_idx, iorq, idxf[iorq]);
-+                      rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pf=%x, idx_0=%x, idx_1=%x, ibit=%x !\n", p0, p1, pf, idx0, idx1, ibit);
-+
-+                      if ((bidx != 5) && (pf <= p0) && (pf < p1)) {
-+                              pf = pf;
-+                              idxf[iorq] = idxf[iorq];
-+                      } else if (p0 < p1) {
-+                              pf = p0;
-+                              idxf[iorq] = idx0 & 0x3F;
-+                      } else {
-+                              pf = p1;
-+                              idxf[iorq] = idx1 & 0x3F;
-+                      }
-+                      rt2x00_dbg(rt2x00dev, "IorQ=%u, idx_final[%u]:%x, pf:%8x\n", iorq, iorq, idxf[iorq], pf);
-+
-+                      rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idxf[iorq]);
-+
-+              }
-+              ibit = ibit >> 1;
-+      }
-+      dc_result[ch_idx][alc_idx][0] = idxf[0];
-+      dc_result[ch_idx][alc_idx][1] = idxf[1];
-+
-+      return;
-+}
-+
-+static void rt2800_iq_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 *ges, u8 *pes)
-+{
-+      u32 p0 = 0, p1 = 0, pf = 0;
-+      char perr = 0, gerr = 0, iq_err = 0;
-+      char pef = 0, gef = 0;
-+      char psta, pend;
-+      char gsta, gend;
-+
-+      u8 ibit = 0x20;
-+      u8 first_search = 0x00, touch_neg_max = 0x00;
-+      char idx0 = 0, idx1 = 0;
-+      u8 gop;
-+      u8 bbp = 0;
-+      char bidx;
-+
-+      rt2x00_info(rt2x00dev, "IQCalibration Start!\n");
-+      for (bidx = 5; bidx >= 1; bidx--) {
-+              for (gop = 0; gop < 2; gop++) {
-+                      rt2x00_dbg(rt2x00dev, "\n========================================================\n");
-+
-+                      if ((gop == 1) || (bidx < 4)) {
-+                              if (gop == 0)
-+                                      iq_err = gerr;
-+                              else
-+                                      iq_err = perr;
-+
-+                              first_search = (gop == 0) ? (bidx == 3) : (bidx == 5);
-+                              touch_neg_max = (gop) ? ((iq_err & 0x0F) == 0x08) : ((iq_err & 0x3F) == 0x20);
-+
-+                              if (touch_neg_max) {
-+                                      p0 = pf;
-+                                      idx0 = iq_err;
-+                              } else {
-+                                      idx0 = iq_err - ibit;
-+                                      bbp = (ch_idx == 0) ? ((gop == 0) ? 0x28 : 0x29): ((gop == 0) ? 0x46 : 0x47);
-+
-+                                      rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                                      rt2800_bbp_write(rt2x00dev, 159, idx0);
-+
-+                                      p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
-+                              }
-+
-+                              idx1 = iq_err + (first_search ? 0 : ibit);
-+                              idx1 = (gop == 0) ? (idx1 & 0x0F) : (idx1 & 0x3F);
-+
-+                              bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47;
-+
-+                              rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                              rt2800_bbp_write(rt2x00dev, 159, idx1);
-+
-+                              p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
-+
-+                              rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pwer_final=%x, idx0=%x, idx1=%x, iq_err=%x, gop=%d, ibit=%x !\n", p0, p1, pf, idx0, idx1, iq_err, gop, ibit);
-+
-+                              if ((!first_search) && (pf <= p0) && (pf < p1)) {
-+                                      pf = pf;
-+                              } else if (p0 < p1) {
-+                                      pf = p0;
-+                                      iq_err = idx0;
-+                              } else {
-+                                      pf = p1;
-+                                      iq_err = idx1;
-+                              }
-+
-+                              bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47;
-+
-+                              rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                              rt2800_bbp_write(rt2x00dev, 159, iq_err);
-+
-+                              if (gop == 0)
-+                                      gerr = iq_err;
-+                              else
-+                                      perr = iq_err;
-+
-+                              rt2x00_dbg(rt2x00dev, "IQCalibration pf=%8x (%2x, %2x) !\n", pf, gerr & 0x0F, perr & 0x3F);
-+
-+                      }
-+              }
-+
-+              if (bidx > 0)
-+                      ibit = (ibit >> 1);
-+      }
-+      gerr = (gerr & 0x08) ? (gerr & 0x0F) - 0x10 : (gerr & 0x0F);
-+      perr = (perr & 0x20) ? (perr & 0x3F) - 0x40 : (perr & 0x3F);
-+
-+      gerr = (gerr < -0x07) ? -0x07 : (gerr > 0x05) ? 0x05 : gerr;
-+      gsta = gerr - 1;
-+      gend = gerr + 2;
-+
-+      perr = (perr < -0x1f) ? -0x1f : (perr > 0x1d) ? 0x1d : perr;
-+      psta = perr - 1;
-+      pend = perr + 2;
-+
-+      for (gef = gsta; gef <= gend; gef = gef + 1)
-+              for (pef = psta; pef <= pend; pef = pef + 1) {
-+                      bbp = (ch_idx == 0) ? 0x28 : 0x46;
-+                      rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                      rt2800_bbp_write(rt2x00dev, 159, gef & 0x0F);
-+
-+                      bbp = (ch_idx == 0) ? 0x29 : 0x47;
-+                      rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                      rt2800_bbp_write(rt2x00dev, 159, pef & 0x3F);
-+
-+                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
-+                      if ((gef == gsta) && (pef == psta)) {
-+                              pf = p1;
-+                              gerr = gef;
-+                              perr = pef;
-+                      }
-+                      else if (pf > p1){
-+                              pf = p1;
-+                              gerr = gef;
-+                              perr = pef;
-+                      }
-+                      rt2x00_dbg(rt2x00dev, "Fine IQCalibration p1=%8x pf=%8x (%2x, %2x) !\n", p1, pf, gef & 0x0F, pef & 0x3F);
-+              }
-+
-+      ges[ch_idx] = gerr & 0x0F;
-+      pes[ch_idx] = perr & 0x3F;
-+
-+      rt2x00_info(rt2x00dev, "IQCalibration Done! CH = %u, (gain=%2x, phase=%2x)\n", ch_idx, gerr & 0x0F, perr & 0x3F);
-+
-+      return;
-+}
-+
-+static void rt2800_rf_aux_tx0_loopback(struct rt2x00_dev *rt2x00dev)
-+{
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x21);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x10);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x1b);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, 0x81);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 4, 2, 0x81);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 4, 34, 0xee);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, 0x2d);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, 0x2d);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, 0x80);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xd7);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0xa2);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x20);
-+}
-+
-+static void rt2800_rf_aux_tx1_loopback(struct rt2x00_dev *rt2x00dev)
-+{
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x22);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x20);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x4b);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, 0x81);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 6, 2, 0x81);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 6, 34, 0xee);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, 0x2d);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, 0x2d);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, 0x80);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, 0xd7);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, 0xa2);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, 0x20);
-+}
-+
-+void rt2800_loft_iq_calibration(struct rt2x00_dev *rt2x00dev)
-+{
-+      rf_reg_pair rf_store[CHAIN_NUM][13];
-+      u32 macorg1 = 0;
-+      u32 macorg2 = 0;
-+      u32 macorg3 = 0;
-+      u32 macorg4 = 0;
-+      u32 macorg5 = 0;
-+      u32 orig528 = 0;
-+      u32 orig52c = 0;
-+
-+      u32 savemacsysctrl = 0, mtxcycle = 0;
-+      u32 macvalue = 0;
-+      u32 mac13b8 = 0;
-+      u32 p0 = 0, p1 = 0;
-+      u32 p0_idx10 = 0, p1_idx10 = 0;
-+
-+      u8 rfvalue;
-+      u8 loft_dc_search_result[CHAIN_NUM][RF_ALC_NUM][2];
-+      u8 ger[CHAIN_NUM], per[CHAIN_NUM];
-+      u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c};
-+      u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F};
-+
-+      u8 vga_gain[] = {14, 14};
-+      u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08};
-+      u8 bbp = 0, ch_idx = 0, rf_alc_idx = 0, idx = 0;
-+      u8 bbpr30, rfb0r39, rfb0r42;
-+      u8 bbpr1;
-+      u8 bbpr4;
-+      u8 bbpr241, bbpr242;
-+      u8 count_step;
-+
-+      savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+      macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
-+      macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
-+      macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
-+      macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-+      macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-+      mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
-+      orig528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
-+      orig52c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
-+
-+      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+      macvalue &= (~0x04);
-+      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
-+
-+      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
-+              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+              if (macvalue & 0x01)
-+                      udelay(50);
-+              else
-+                      break;
-+      }
-+
-+      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+      macvalue &= (~0x08);
-+      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
-+
-+      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
-+              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+              if (macvalue & 0x02)
-+                      udelay(50);
-+              else
-+                      break;
-+      }
-+
-+      for (ch_idx = 0; ch_idx < 2; ch_idx++) {
-+              rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
-+      }
-+
-+      bbpr30 = rt2800_bbp_read(rt2x00dev, 30);
-+      rfb0r39 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 39);
-+      rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
-+
-+      rt2800_bbp_write(rt2x00dev, 30, 0x1F);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, 0x80);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x5B);
-+
-+      rt2800_bbp_write(rt2x00dev, 23, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 24, 0x00);
-+
-+      rt2800_setbbptonegenerator(rt2x00dev);
-+
-+      for (ch_idx = 0; ch_idx < 2; ch_idx ++) {
-+              rt2800_bbp_write(rt2x00dev, 23, 0x00);
-+              rt2800_bbp_write(rt2x00dev, 24, 0x00);
-+              rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00);
-+              rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
-+              rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
-+              rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
-+              rt2800_register_write(rt2x00dev, 0x13b8, 0x10);
-+              udelay(1);
-+
-+              if (ch_idx == 0) {
-+                      rt2800_rf_aux_tx0_loopback(rt2x00dev);
-+              } else {
-+                      rt2800_rf_aux_tx1_loopback(rt2x00dev);
-+              }
-+              udelay(1);
-+
-+              if (ch_idx == 0) {
-+                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
-+              } else {
-+                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
-+              }
-+
-+              rt2800_bbp_write(rt2x00dev, 158, 0x05);
-+              rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+
-+              rt2800_bbp_write(rt2x00dev, 158, 0x01);
-+              if (ch_idx == 0)
-+                      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+              else
-+                      rt2800_bbp_write(rt2x00dev, 159, 0x01);
-+
-+              vga_gain[ch_idx] = 18;
-+              for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
-+                      rt2800_bbp_write(rt2x00dev, 23, bbp_2324gain[rf_alc_idx]);
-+                      rt2800_bbp_write(rt2x00dev, 24, bbp_2324gain[rf_alc_idx]);
-+
-+                      macvalue = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-+                      macvalue &= (~0x0000F1F1);
-+                      macvalue |= (rf_gain[rf_alc_idx] << 4);
-+                      macvalue |= (rf_gain[rf_alc_idx] << 12);
-+                      rt2800_register_write(rt2x00dev, RF_CONTROL3, macvalue);
-+                      macvalue = (0x0000F1F1);
-+                      rt2800_register_write(rt2x00dev, RF_BYPASS3, macvalue);
-+
-+                      if (rf_alc_idx == 0) {
-+                              rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x21);
-+                              for (;vga_gain[ch_idx] > 0;vga_gain[ch_idx] = vga_gain[ch_idx] - 2) {
-+                                      rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
-+                                      rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
-+                                      rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
-+                                      rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
-+                                      rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
-+                                      p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
-+                                      rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x21);
-+                                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
-+                                      rt2x00_dbg(rt2x00dev, "LOFT AGC %d %d\n", p0, p1);
-+                                      if ((p0 < 7000*7000) && (p1 < (7000*7000))) {
-+                                              break;
-+                                      }
-+                              }
-+
-+                              rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
-+                              rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
-+
-+                              rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]);
-+
-+                              if (vga_gain[ch_idx] < 0)
-+                                      vga_gain[ch_idx] = 0;
-+                      }
-+
-+                      rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
-+
-+                      rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
-+                      rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
-+
-+                      rt2800_loft_search(rt2x00dev, ch_idx, rf_alc_idx, loft_dc_search_result);
-+              }
-+      }
-+
-+      for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
-+              for (idx = 0; idx < 4; idx++) {
-+                      rt2800_bbp_write(rt2x00dev, 158, 0xB0);
-+                      bbp = (idx<<2) + rf_alc_idx;
-+                      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+                      rt2x00_dbg(rt2x00dev, " ALC %2x,", bbp);
-+
-+                      rt2800_bbp_write(rt2x00dev, 158, 0xb1);
-+                      bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x00];
-+                      bbp = bbp & 0x3F;
-+                      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+                      rt2x00_dbg(rt2x00dev, " I0 %2x,", bbp);
-+
-+                      rt2800_bbp_write(rt2x00dev, 158, 0xb2);
-+                      bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x01];
-+                      bbp = bbp & 0x3F;
-+                      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+                      rt2x00_dbg(rt2x00dev, " Q0 %2x,", bbp);
-+
-+                      rt2800_bbp_write(rt2x00dev, 158, 0xb8);
-+                      bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x00];
-+                      bbp = bbp & 0x3F;
-+                      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+                      rt2x00_dbg(rt2x00dev, " I1 %2x,", bbp);
-+
-+                      rt2800_bbp_write(rt2x00dev, 158, 0xb9);
-+                      bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x01];
-+                      bbp = bbp & 0x3F;
-+                      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+                      rt2x00_dbg(rt2x00dev, " Q1 %2x\n", bbp);
-+              }
-+      }
-+
-+      rt2800_bbp_write(rt2x00dev, 23, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 24, 0x00);
-+
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+
-+      bbp = 0x00;
-+      rt2800_bbp_write(rt2x00dev, 244, 0x00);
-+
-+      rt2800_bbp_write(rt2x00dev, 21, 0x01);
-+      udelay(1);
-+      rt2800_bbp_write(rt2x00dev, 21, 0x00);
-+
-+      rt2800_rf_configrecover(rt2x00dev, rf_store);
-+
-+      rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
-+      udelay(1);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
-+      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL2, orig528);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS2, orig52c);
-+      rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
-+
-+      rt2x00_info(rt2x00dev, "LOFT Calibration Done!\n");
-+
-+      savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+      macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
-+      macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
-+      macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
-+      macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-+      macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-+
-+      bbpr1 = rt2800_bbp_read(rt2x00dev, 1);
-+      bbpr4 = rt2800_bbp_read(rt2x00dev, 4);
-+      bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
-+      bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
-+      mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
-+
-+      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+      macvalue &= (~0x04);
-+      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
-+      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
-+              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+              if (macvalue & 0x01)
-+                      udelay(50);
-+              else
-+                      break;
-+      }
-+
-+      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+      macvalue &= (~0x08);
-+      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
-+      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
-+              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+              if (macvalue & 0x02)
-+                      udelay(50);
-+              else
-+                      break;
-+      }
-+
-+      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+              rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000101);
-+              rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
-+      }
-+
-+      rt2800_bbp_write(rt2x00dev, 23, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 24, 0x00);
-+
-+      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+              rt2800_bbp_write(rt2x00dev, 4, bbpr4 & (~0x18));
-+              rt2800_bbp_write(rt2x00dev, 21, 0x01);
-+              udelay(1);
-+              rt2800_bbp_write(rt2x00dev, 21, 0x00);
-+
-+              rt2800_bbp_write(rt2x00dev, 241, 0x14);
-+              rt2800_bbp_write(rt2x00dev, 242, 0x80);
-+              rt2800_bbp_write(rt2x00dev, 244, 0x31);
-+      } else {
-+              rt2800_setbbptonegenerator(rt2x00dev);
-+      }
-+
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
-+      udelay(1);
-+
-+      rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
-+
-+      if (!test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+              rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000000);
-+              rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
-+      }
-+
-+      rt2800_register_write(rt2x00dev, 0x13b8, 0x00000010);
-+
-+      for (ch_idx = 0; ch_idx < 2; ch_idx++) {
-+              rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
-+      }
-+
-+      rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x3B);
-+      rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x3B);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x03);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x60);
-+      rt2800_bbp_write(rt2x00dev, 158, 0xB0);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x80);
-+
-+      for (ch_idx = 0; ch_idx < 2; ch_idx ++) {
-+              rt2800_bbp_write(rt2x00dev, 23, 0x00);
-+              rt2800_bbp_write(rt2x00dev, 24, 0x00);
-+
-+              if (ch_idx == 0) {
-+                      rt2800_bbp_write(rt2x00dev, 158, 0x01);
-+                      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+                              bbp = bbpr1 & (~0x18);
-+                              bbp = bbp | 0x00;
-+                              rt2800_bbp_write(rt2x00dev, 1, bbp);
-+                      }
-+                      rt2800_rf_aux_tx0_loopback(rt2x00dev);
-+                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
-+              } else {
-+                      rt2800_bbp_write(rt2x00dev, 158, 0x01);
-+                      rt2800_bbp_write(rt2x00dev, 159, 0x01);
-+                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
-+                              bbp = bbpr1 & (~0x18);
-+                              bbp = bbp | 0x08;
-+                              rt2800_bbp_write(rt2x00dev, 1, bbp);
-+                      }
-+                      rt2800_rf_aux_tx1_loopback(rt2x00dev);
-+                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
-+              }
-+
-+              rt2800_bbp_write(rt2x00dev, 158, 0x05);
-+              rt2800_bbp_write(rt2x00dev, 159, 0x04);
-+
-+              bbp = (ch_idx == 0) ? 0x28 : 0x46;
-+              rt2800_bbp_write(rt2x00dev, 158, bbp);
-+              rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+
-+              if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+                      rt2800_bbp_write(rt2x00dev, 23, 0x06);
-+                      rt2800_bbp_write(rt2x00dev, 24, 0x06);
-+                      count_step = 1;
-+              } else {
-+                      rt2800_bbp_write(rt2x00dev, 23, 0x1F);
-+                      rt2800_bbp_write(rt2x00dev, 24, 0x1F);
-+                      count_step = 2;
-+              }
-+
-+              for (;vga_gain[ch_idx] < 19; vga_gain[ch_idx]=(vga_gain[ch_idx] + count_step)) {
-+                      rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
-+                      rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
-+                      rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
-+
-+                      bbp = (ch_idx == 0) ? 0x29 : 0x47;
-+                      rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+                      p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
-+                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+                              p0_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
-+                      }
-+
-+                      bbp = (ch_idx == 0) ? 0x29 : 0x47;
-+                      rt2800_bbp_write(rt2x00dev, 158, bbp);
-+                      rt2800_bbp_write(rt2x00dev, 159, 0x21);
-+                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
-+                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
-+                              p1_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
-+                      }
-+
-+                      rt2x00_dbg(rt2x00dev, "IQ AGC %d %d\n", p0, p1);
-+
-+                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+                              rt2x00_dbg(rt2x00dev, "IQ AGC IDX 10 %d %d\n", p0_idx10, p1_idx10);
-+                              if ((p0_idx10 > 7000*7000) || (p1_idx10 > 7000*7000)) {
-+                                      if (vga_gain[ch_idx]!=0)
-+                                              vga_gain[ch_idx] = vga_gain[ch_idx]-1;
-+                                      break;
-+                              }
-+                      }
-+
-+                      if ((p0 > 2500*2500) || (p1 > 2500*2500)) {
-+                              break;
-+                      }
-+              }
-+
-+              if (vga_gain[ch_idx] > 18)
-+                      vga_gain[ch_idx] = 18;
-+              rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]);
-+
-+              bbp = (ch_idx == 0) ? 0x29 : 0x47;
-+              rt2800_bbp_write(rt2x00dev, 158, bbp);
-+              rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+
-+              rt2800_iq_search(rt2x00dev, ch_idx, ger, per);
-+      }
-+
-+      rt2800_bbp_write(rt2x00dev, 23, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 24, 0x00);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x28);
-+      bbp = ger[CHAIN_0] & 0x0F;
-+      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x29);
-+      bbp = per[CHAIN_0] & 0x3F;
-+      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x46);
-+      bbp = ger[CHAIN_1] & 0x0F;
-+      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x47);
-+      bbp = per[CHAIN_1] & 0x3F;
-+      rt2800_bbp_write(rt2x00dev, 159, bbp);
-+
-+      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+              rt2800_bbp_write(rt2x00dev, 1, bbpr1);
-+              rt2800_bbp_write(rt2x00dev, 241, bbpr241);
-+              rt2800_bbp_write(rt2x00dev, 242, bbpr242);
-+      }
-+      rt2800_bbp_write(rt2x00dev, 244, 0x00);
-+
-+      rt2800_bbp_write(rt2x00dev, 158, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+      rt2800_bbp_write(rt2x00dev, 158, 0xB0);
-+      rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+
-+      rt2800_bbp_write(rt2x00dev, 30, bbpr30);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, rfb0r39);
-+      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
-+
-+      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+              rt2800_bbp_write(rt2x00dev, 4, bbpr4);
-+      }
-+
-+      rt2800_bbp_write(rt2x00dev, 21, 0x01);
-+      udelay(1);
-+      rt2800_bbp_write(rt2x00dev, 21, 0x00);
-+
-+      rt2800_rf_configrecover(rt2x00dev, rf_store);
-+
-+      rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
-+      udelay(1);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
-+      rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
-+      rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
-+      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
-+      rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
-+
-+      rt2x00_info(rt2x00dev, "TX IQ Calibration Done!\n");
-+
-+      return;
-+}
-+
- static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
-                                      bool set_bw, bool is_ht40)
- {
-@@ -9691,6 +10628,7 @@ static void rt2800_init_rfcsr_6352(struc
-       rt2800_rxdcoc_calibration(rt2x00dev);
-       rt2800_bw_filter_calibration(rt2x00dev, true);
-       rt2800_bw_filter_calibration(rt2x00dev, false);
-+      rt2800_loft_iq_calibration(rt2x00dev);
-       rt2800_rxiq_calibration(rt2x00dev);
- }
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -17,6 +17,16 @@
- #define WCID_START    33
- #define WCID_END      222
- #define STA_IDS_SIZE  (WCID_END - WCID_START + 2)
-+#define CHAIN_0               0x0
-+#define CHAIN_1               0x1
-+#define RF_ALC_NUM    6
-+#define CHAIN_NUM     2
-+
-+typedef struct rf_reg_pair {
-+      u8 bank;
-+      u8 reg;
-+      u8 value;
-+} rf_reg_pair;
- /* RT2800 driver data structure */
- struct rt2800_drv_data {
diff --git a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch
new file mode 100644 (file)
index 0000000..0fdbaae
--- /dev/null
@@ -0,0 +1,35 @@
+From 5f921753b95927c964a5061b5b64c310b968ff3e Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:43:14 +0100
+Subject: [PATCH 08/16] rt2x00: don't run Rt5592 IQ calibration on MT7620
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+The function rt2800_iq_calibrate is intended for Rt5592 only.
+Don't call it for MT7620 which has it's own calibration functions.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -4366,7 +4366,8 @@ static void rt2800_config_channel(struct
+               reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
+               rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+-              rt2800_iq_calibrate(rt2x00dev, rf->channel);
++              if (!rt2x00_rt(rt2x00dev, RT6352))
++                      rt2800_iq_calibrate(rt2x00dev, rf->channel);
+       }
+       if (rt2x00_rt(rt2x00dev, RT6352)) {
diff --git a/package/kernel/mac80211/patches/rt2x00/987-rt2x00-add-TX-LOFT-calibration.patch b/package/kernel/mac80211/patches/rt2x00/987-rt2x00-add-TX-LOFT-calibration.patch
new file mode 100644 (file)
index 0000000..4ce532b
--- /dev/null
@@ -0,0 +1,984 @@
+From e02adea15f762d2add77b2b7714706f5c3c2f9c9 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 11 Jan 2018 19:53:49 +0100
+Subject: [PATCH 09/16] rt2x00: add TX LOFT calibration for MT7620
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
+
+Add TX LOFT calibration from mtk driver.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c    | 922 ++++++++++++++++++
+ .../net/wireless/ralink/rt2x00/rt2800lib.h    |  10 +
+ 2 files changed, 932 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -9080,6 +9080,927 @@ restore_value:
+       rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
+ }
++static void rt2800_rf_configstore(struct rt2x00_dev *rt2x00dev,
++                                struct rf_reg_pair rf_reg_record[][13], u8 chain)
++{
++      u8 rfvalue = 0;
++
++      if (chain == CHAIN_0) {
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
++              rf_reg_record[CHAIN_0][0].bank = 0;
++              rf_reg_record[CHAIN_0][0].reg = 1;
++              rf_reg_record[CHAIN_0][0].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
++              rf_reg_record[CHAIN_0][1].bank = 0;
++              rf_reg_record[CHAIN_0][1].reg = 2;
++              rf_reg_record[CHAIN_0][1].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
++              rf_reg_record[CHAIN_0][2].bank = 0;
++              rf_reg_record[CHAIN_0][2].reg = 35;
++              rf_reg_record[CHAIN_0][2].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
++              rf_reg_record[CHAIN_0][3].bank = 0;
++              rf_reg_record[CHAIN_0][3].reg = 42;
++              rf_reg_record[CHAIN_0][3].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
++              rf_reg_record[CHAIN_0][4].bank = 4;
++              rf_reg_record[CHAIN_0][4].reg = 0;
++              rf_reg_record[CHAIN_0][4].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 2);
++              rf_reg_record[CHAIN_0][5].bank = 4;
++              rf_reg_record[CHAIN_0][5].reg = 2;
++              rf_reg_record[CHAIN_0][5].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 34);
++              rf_reg_record[CHAIN_0][6].bank = 4;
++              rf_reg_record[CHAIN_0][6].reg = 34;
++              rf_reg_record[CHAIN_0][6].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
++              rf_reg_record[CHAIN_0][7].bank = 5;
++              rf_reg_record[CHAIN_0][7].reg = 3;
++              rf_reg_record[CHAIN_0][7].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
++              rf_reg_record[CHAIN_0][8].bank = 5;
++              rf_reg_record[CHAIN_0][8].reg = 4;
++              rf_reg_record[CHAIN_0][8].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
++              rf_reg_record[CHAIN_0][9].bank = 5;
++              rf_reg_record[CHAIN_0][9].reg = 17;
++              rf_reg_record[CHAIN_0][9].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
++              rf_reg_record[CHAIN_0][10].bank = 5;
++              rf_reg_record[CHAIN_0][10].reg = 18;
++              rf_reg_record[CHAIN_0][10].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
++              rf_reg_record[CHAIN_0][11].bank = 5;
++              rf_reg_record[CHAIN_0][11].reg = 19;
++              rf_reg_record[CHAIN_0][11].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
++              rf_reg_record[CHAIN_0][12].bank = 5;
++              rf_reg_record[CHAIN_0][12].reg = 20;
++              rf_reg_record[CHAIN_0][12].value = rfvalue;
++      } else if (chain == CHAIN_1) {
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
++              rf_reg_record[CHAIN_1][0].bank = 0;
++              rf_reg_record[CHAIN_1][0].reg = 1;
++              rf_reg_record[CHAIN_1][0].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
++              rf_reg_record[CHAIN_1][1].bank = 0;
++              rf_reg_record[CHAIN_1][1].reg = 2;
++              rf_reg_record[CHAIN_1][1].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
++              rf_reg_record[CHAIN_1][2].bank = 0;
++              rf_reg_record[CHAIN_1][2].reg = 35;
++              rf_reg_record[CHAIN_1][2].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
++              rf_reg_record[CHAIN_1][3].bank = 0;
++              rf_reg_record[CHAIN_1][3].reg = 42;
++              rf_reg_record[CHAIN_1][3].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
++              rf_reg_record[CHAIN_1][4].bank = 6;
++              rf_reg_record[CHAIN_1][4].reg = 0;
++              rf_reg_record[CHAIN_1][4].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 2);
++              rf_reg_record[CHAIN_1][5].bank = 6;
++              rf_reg_record[CHAIN_1][5].reg = 2;
++              rf_reg_record[CHAIN_1][5].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 34);
++              rf_reg_record[CHAIN_1][6].bank = 6;
++              rf_reg_record[CHAIN_1][6].reg = 34;
++              rf_reg_record[CHAIN_1][6].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
++              rf_reg_record[CHAIN_1][7].bank = 7;
++              rf_reg_record[CHAIN_1][7].reg = 3;
++              rf_reg_record[CHAIN_1][7].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
++              rf_reg_record[CHAIN_1][8].bank = 7;
++              rf_reg_record[CHAIN_1][8].reg = 4;
++              rf_reg_record[CHAIN_1][8].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
++              rf_reg_record[CHAIN_1][9].bank = 7;
++              rf_reg_record[CHAIN_1][9].reg = 17;
++              rf_reg_record[CHAIN_1][9].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
++              rf_reg_record[CHAIN_1][10].bank = 7;
++              rf_reg_record[CHAIN_1][10].reg = 18;
++              rf_reg_record[CHAIN_1][10].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
++              rf_reg_record[CHAIN_1][11].bank = 7;
++              rf_reg_record[CHAIN_1][11].reg = 19;
++              rf_reg_record[CHAIN_1][11].value = rfvalue;
++              rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
++              rf_reg_record[CHAIN_1][12].bank = 7;
++              rf_reg_record[CHAIN_1][12].reg = 20;
++              rf_reg_record[CHAIN_1][12].value = rfvalue;
++      } else {
++              rt2x00_warn(rt2x00dev, "Unknown chain = %u\n", chain);
++      }
++}
++
++static void rt2800_rf_configrecover(struct rt2x00_dev *rt2x00dev,
++                                  struct rf_reg_pair rf_record[][13])
++{
++      u8 chain_index = 0, record_index = 0;
++      u8 bank = 0, rf_register = 0, value = 0;
++
++      for (chain_index = 0; chain_index < 2; chain_index++) {
++              for (record_index = 0; record_index < 13; record_index++) {
++                      bank = rf_record[chain_index][record_index].bank;
++                      rf_register = rf_record[chain_index][record_index].reg;
++                      value = rf_record[chain_index][record_index].value;
++                      rt2800_rfcsr_write_bank(rt2x00dev, bank, rf_register, value);
++                      rt2x00_dbg(rt2x00dev, "bank: %d, rf_register: %d, value: %x\n",
++                                 bank, rf_register, value);
++              }
++      }
++}
++
++static void rt2800_setbbptonegenerator(struct rt2x00_dev *rt2x00dev)
++{
++      rt2800_bbp_write(rt2x00dev, 158, 0xAA);
++      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xAB);
++      rt2800_bbp_write(rt2x00dev, 159, 0x0A);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xAC);
++      rt2800_bbp_write(rt2x00dev, 159, 0x3F);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xAD);
++      rt2800_bbp_write(rt2x00dev, 159, 0x3F);
++
++      rt2800_bbp_write(rt2x00dev, 244, 0x40);
++}
++
++static u32 rt2800_do_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx, u8 read_neg)
++{
++      u32 macvalue = 0;
++      int fftout_i = 0, fftout_q = 0;
++      u32 ptmp = 0, pint = 0;
++      u8 bbp = 0;
++      u8 tidxi;
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x00);
++      rt2800_bbp_write(rt2x00dev, 159, 0x9b);
++
++      bbp = 0x9b;
++
++      while (bbp == 0x9b) {
++              usleep_range(10, 50);
++              bbp = rt2800_bbp_read(rt2x00dev, 159);
++              bbp = bbp & 0xff;
++      }
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xba);
++      rt2800_bbp_write(rt2x00dev, 159, tidx);
++      rt2800_bbp_write(rt2x00dev, 159, tidx);
++      rt2800_bbp_write(rt2x00dev, 159, tidx);
++
++      macvalue = rt2800_register_read(rt2x00dev, 0x057C);
++
++      fftout_i = (macvalue >> 16);
++      fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
++      fftout_q = (macvalue & 0xffff);
++      fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
++      ptmp = (fftout_i * fftout_i);
++      ptmp = ptmp + (fftout_q * fftout_q);
++      pint = ptmp;
++      rt2x00_dbg(rt2x00dev, "I = %d,  Q = %d, power = %x\n", fftout_i, fftout_q, pint);
++      if (read_neg) {
++              pint = pint >> 1;
++              tidxi = 0x40 - tidx;
++              tidxi = tidxi & 0x3f;
++
++              rt2800_bbp_write(rt2x00dev, 158, 0xba);
++              rt2800_bbp_write(rt2x00dev, 159, tidxi);
++              rt2800_bbp_write(rt2x00dev, 159, tidxi);
++              rt2800_bbp_write(rt2x00dev, 159, tidxi);
++
++              macvalue = rt2800_register_read(rt2x00dev, 0x057C);
++
++              fftout_i = (macvalue >> 16);
++              fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
++              fftout_q = (macvalue & 0xffff);
++              fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
++              ptmp = (fftout_i * fftout_i);
++              ptmp = ptmp + (fftout_q * fftout_q);
++              ptmp = ptmp >> 1;
++              pint = pint + ptmp;
++      }
++
++      return pint;
++}
++
++static u32 rt2800_read_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx)
++{
++      u32 macvalue = 0;
++      int fftout_i = 0, fftout_q = 0;
++      u32 ptmp = 0, pint = 0;
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xBA);
++      rt2800_bbp_write(rt2x00dev, 159, tidx);
++      rt2800_bbp_write(rt2x00dev, 159, tidx);
++      rt2800_bbp_write(rt2x00dev, 159, tidx);
++
++      macvalue = rt2800_register_read(rt2x00dev, 0x057C);
++
++      fftout_i = (macvalue >> 16);
++      fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
++      fftout_q = (macvalue & 0xffff);
++      fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
++      ptmp = (fftout_i * fftout_i);
++      ptmp = ptmp + (fftout_q * fftout_q);
++      pint = ptmp;
++
++      return pint;
++}
++
++static void rt2800_write_dc(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc, u8 iorq, u8 dc)
++{
++      u8 bbp = 0;
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xb0);
++      bbp = alc | 0x80;
++      rt2800_bbp_write(rt2x00dev, 159, bbp);
++
++      if (ch_idx == 0)
++              bbp = (iorq == 0) ? 0xb1 : 0xb2;
++      else
++              bbp = (iorq == 0) ? 0xb8 : 0xb9;
++
++      rt2800_bbp_write(rt2x00dev, 158, bbp);
++      bbp = dc;
++      rt2800_bbp_write(rt2x00dev, 159, bbp);
++}
++
++static void rt2800_loft_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx,
++                             u8 alc_idx, u8 dc_result[][RF_ALC_NUM][2])
++{
++      u32 p0 = 0, p1 = 0, pf = 0;
++      char idx0 = 0, idx1 = 0;
++      u8 idxf[] = {0x00, 0x00};
++      u8 ibit = 0x20;
++      u8 iorq;
++      char bidx;
++
++      rt2800_bbp_write(rt2x00dev, 158, 0xb0);
++      rt2800_bbp_write(rt2x00dev, 159, 0x80);
++
++      for (bidx = 5; bidx >= 0; bidx--) {
++              for (iorq = 0; iorq <= 1; iorq++) {
++                      rt2x00_dbg(rt2x00dev, "\n========================================================\n");
++
++                      if (idxf[iorq] == 0x20) {
++                              idx0 = 0x20;
++                              p0 = pf;
++                      } else {
++                              idx0 = idxf[iorq] - ibit;
++                              idx0 = idx0 & 0x3F;
++                              rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx0);
++                              p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
++                      }
++
++                      idx1 = idxf[iorq] + (bidx == 5 ? 0 : ibit);
++                      idx1 = idx1 & 0x3F;
++                      rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx1);
++                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
++
++                      rt2x00_dbg(rt2x00dev, "alc=%u, IorQ=%u, idx_final=%2x\n",
++                                 alc_idx, iorq, idxf[iorq]);
++                      rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pf=%x, idx_0=%x, idx_1=%x, ibit=%x\n",
++                                 p0, p1, pf, idx0, idx1, ibit);
++
++                      if (bidx != 5 && pf <= p0 && pf < p1) {
++                              idxf[iorq] = idxf[iorq];
++                      } else if (p0 < p1) {
++                              pf = p0;
++                              idxf[iorq] = idx0 & 0x3F;
++                      } else {
++                              pf = p1;
++                              idxf[iorq] = idx1 & 0x3F;
++                      }
++                      rt2x00_dbg(rt2x00dev, "IorQ=%u, idx_final[%u]:%x, pf:%8x\n",
++                                 iorq, iorq, idxf[iorq], pf);
++
++                      rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idxf[iorq]);
++              }
++              ibit = ibit >> 1;
++      }
++      dc_result[ch_idx][alc_idx][0] = idxf[0];
++      dc_result[ch_idx][alc_idx][1] = idxf[1];
++}
++
++static void rt2800_iq_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 *ges, u8 *pes)
++{
++      u32 p0 = 0, p1 = 0, pf = 0;
++      char perr = 0, gerr = 0, iq_err = 0;
++      char pef = 0, gef = 0;
++      char psta, pend;
++      char gsta, gend;
++
++      u8 ibit = 0x20;
++      u8 first_search = 0x00, touch_neg_max = 0x00;
++      char idx0 = 0, idx1 = 0;
++      u8 gop;
++      u8 bbp = 0;
++      char bidx;
++
++      for (bidx = 5; bidx >= 1; bidx--) {
++              for (gop = 0; gop < 2; gop++) {
++                      rt2x00_dbg(rt2x00dev, "\n==============================================\n");
++
++                      if (gop == 1 || bidx < 4) {
++                              if (gop == 0)
++                                      iq_err = gerr;
++                              else
++                                      iq_err = perr;
++
++                              first_search = (gop == 0) ? (bidx == 3) : (bidx == 5);
++                              touch_neg_max = (gop) ? ((iq_err & 0x0F) == 0x08) :
++                                                      ((iq_err & 0x3F) == 0x20);
++
++                              if (touch_neg_max) {
++                                      p0 = pf;
++                                      idx0 = iq_err;
++                              } else {
++                                      idx0 = iq_err - ibit;
++                                      bbp = (ch_idx == 0) ? ((gop == 0) ? 0x28 : 0x29) :
++                                                            ((gop == 0) ? 0x46 : 0x47);
++
++                                      rt2800_bbp_write(rt2x00dev, 158, bbp);
++                                      rt2800_bbp_write(rt2x00dev, 159, idx0);
++
++                                      p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
++                              }
++
++                              idx1 = iq_err + (first_search ? 0 : ibit);
++                              idx1 = (gop == 0) ? (idx1 & 0x0F) : (idx1 & 0x3F);
++
++                              bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 :
++                                    (gop == 0) ? 0x46 : 0x47;
++
++                              rt2800_bbp_write(rt2x00dev, 158, bbp);
++                              rt2800_bbp_write(rt2x00dev, 159, idx1);
++
++                              p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
++
++                              rt2x00_dbg(rt2x00dev,
++                                         "p0=%x, p1=%x, pwer_final=%x, idx0=%x, idx1=%x, iq_err=%x, gop=%d, ibit=%x\n",
++                                         p0, p1, pf, idx0, idx1, iq_err, gop, ibit);
++
++                              if (!(!first_search && pf <= p0 && pf < p1)) {
++                                      if (p0 < p1) {
++                                              pf = p0;
++                                              iq_err = idx0;
++                                      } else {
++                                              pf = p1;
++                                              iq_err = idx1;
++                                      }
++                              }
++
++                              bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 :
++                                                    (gop == 0) ? 0x46 : 0x47;
++
++                              rt2800_bbp_write(rt2x00dev, 158, bbp);
++                              rt2800_bbp_write(rt2x00dev, 159, iq_err);
++
++                              if (gop == 0)
++                                      gerr = iq_err;
++                              else
++                                      perr = iq_err;
++
++                              rt2x00_dbg(rt2x00dev, "IQCalibration pf=%8x (%2x, %2x) !\n",
++                                         pf, gerr & 0x0F, perr & 0x3F);
++                      }
++              }
++
++              if (bidx > 0)
++                      ibit = (ibit >> 1);
++      }
++      gerr = (gerr & 0x08) ? (gerr & 0x0F) - 0x10 : (gerr & 0x0F);
++      perr = (perr & 0x20) ? (perr & 0x3F) - 0x40 : (perr & 0x3F);
++
++      gerr = (gerr < -0x07) ? -0x07 : (gerr > 0x05) ? 0x05 : gerr;
++      gsta = gerr - 1;
++      gend = gerr + 2;
++
++      perr = (perr < -0x1f) ? -0x1f : (perr > 0x1d) ? 0x1d : perr;
++      psta = perr - 1;
++      pend = perr + 2;
++
++      for (gef = gsta; gef <= gend; gef = gef + 1)
++              for (pef = psta; pef <= pend; pef = pef + 1) {
++                      bbp = (ch_idx == 0) ? 0x28 : 0x46;
++                      rt2800_bbp_write(rt2x00dev, 158, bbp);
++                      rt2800_bbp_write(rt2x00dev, 159, gef & 0x0F);
++
++                      bbp = (ch_idx == 0) ? 0x29 : 0x47;
++                      rt2800_bbp_write(rt2x00dev, 158, bbp);
++                      rt2800_bbp_write(rt2x00dev, 159, pef & 0x3F);
++
++                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
++                      if (gef == gsta && pef == psta) {
++                              pf = p1;
++                              gerr = gef;
++                              perr = pef;
++                      } else if (pf > p1) {
++                              pf = p1;
++                              gerr = gef;
++                              perr = pef;
++                      }
++                      rt2x00_dbg(rt2x00dev, "Fine IQCalibration p1=%8x pf=%8x (%2x, %2x) !\n",
++                                 p1, pf, gef & 0x0F, pef & 0x3F);
++              }
++
++      ges[ch_idx] = gerr & 0x0F;
++      pes[ch_idx] = perr & 0x3F;
++}
++
++static void rt2800_rf_aux_tx0_loopback(struct rt2x00_dev *rt2x00dev)
++{
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x21);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x10);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x1b);
++      rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, 0x81);
++      rt2800_rfcsr_write_bank(rt2x00dev, 4, 2, 0x81);
++      rt2800_rfcsr_write_bank(rt2x00dev, 4, 34, 0xee);
++      rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, 0x2d);
++      rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, 0x2d);
++      rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, 0x80);
++      rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xd7);
++      rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0xa2);
++      rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x20);
++}
++
++static void rt2800_rf_aux_tx1_loopback(struct rt2x00_dev *rt2x00dev)
++{
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x22);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x20);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x4b);
++      rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, 0x81);
++      rt2800_rfcsr_write_bank(rt2x00dev, 6, 2, 0x81);
++      rt2800_rfcsr_write_bank(rt2x00dev, 6, 34, 0xee);
++      rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, 0x2d);
++      rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, 0x2d);
++      rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, 0x80);
++      rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, 0xd7);
++      rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, 0xa2);
++      rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, 0x20);
++}
++
++void rt2800_loft_iq_calibration(struct rt2x00_dev *rt2x00dev)
++{
++      struct rf_reg_pair rf_store[CHAIN_NUM][13];
++      u32 macorg1 = 0;
++      u32 macorg2 = 0;
++      u32 macorg3 = 0;
++      u32 macorg4 = 0;
++      u32 macorg5 = 0;
++      u32 orig528 = 0;
++      u32 orig52c = 0;
++
++      u32 savemacsysctrl = 0, mtxcycle = 0;
++      u32 macvalue = 0;
++      u32 mac13b8 = 0;
++      u32 p0 = 0, p1 = 0;
++      u32 p0_idx10 = 0, p1_idx10 = 0;
++
++      u8 rfvalue;
++      u8 loft_dc_search_result[CHAIN_NUM][RF_ALC_NUM][2];
++      u8 ger[CHAIN_NUM], per[CHAIN_NUM];
++      u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c};
++      u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
++                               0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F};
++      u8 vga_gain[] = {14, 14};
++      u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08};
++      u8 bbp = 0, ch_idx = 0, rf_alc_idx = 0, idx = 0;
++      u8 bbpr30, rfb0r39, rfb0r42;
++      u8 bbpr1;
++      u8 bbpr4;
++      u8 bbpr241, bbpr242;
++      u8 count_step;
++
++      savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++      macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
++      macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
++      macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
++      macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
++      macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
++      mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
++      orig528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
++      orig52c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
++
++      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++      macvalue &= (~0x04);
++      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++
++      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
++              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
++              if (macvalue & 0x01)
++                      usleep_range(50, 100);
++              else
++                      break;
++      }
++
++      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++      macvalue &= (~0x08);
++      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++
++      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
++              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
++              if (macvalue & 0x02)
++                      usleep_range(50, 100);
++              else
++                      break;
++      }
++
++      for (ch_idx = 0; ch_idx < 2; ch_idx++)
++              rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
++
++      bbpr30 = rt2800_bbp_read(rt2x00dev, 30);
++      rfb0r39 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 39);
++      rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
++
++      rt2800_bbp_write(rt2x00dev, 30, 0x1F);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, 0x80);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x5B);
++
++      rt2800_bbp_write(rt2x00dev, 23, 0x00);
++      rt2800_bbp_write(rt2x00dev, 24, 0x00);
++
++      rt2800_setbbptonegenerator(rt2x00dev);
++
++      for (ch_idx = 0; ch_idx < 2; ch_idx++) {
++              rt2800_bbp_write(rt2x00dev, 23, 0x00);
++              rt2800_bbp_write(rt2x00dev, 24, 0x00);
++              rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00);
++              rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
++              rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
++              rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
++              rt2800_register_write(rt2x00dev, 0x13b8, 0x10);
++              udelay(1);
++
++              if (ch_idx == 0)
++                      rt2800_rf_aux_tx0_loopback(rt2x00dev);
++              else
++                      rt2800_rf_aux_tx1_loopback(rt2x00dev);
++
++              udelay(1);
++
++              if (ch_idx == 0)
++                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
++              else
++                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
++
++              rt2800_bbp_write(rt2x00dev, 158, 0x05);
++              rt2800_bbp_write(rt2x00dev, 159, 0x00);
++
++              rt2800_bbp_write(rt2x00dev, 158, 0x01);
++              if (ch_idx == 0)
++                      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++              else
++                      rt2800_bbp_write(rt2x00dev, 159, 0x01);
++
++              vga_gain[ch_idx] = 18;
++              for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
++                      rt2800_bbp_write(rt2x00dev, 23, bbp_2324gain[rf_alc_idx]);
++                      rt2800_bbp_write(rt2x00dev, 24, bbp_2324gain[rf_alc_idx]);
++
++                      macvalue = rt2800_register_read(rt2x00dev, RF_CONTROL3);
++                      macvalue &= (~0x0000F1F1);
++                      macvalue |= (rf_gain[rf_alc_idx] << 4);
++                      macvalue |= (rf_gain[rf_alc_idx] << 12);
++                      rt2800_register_write(rt2x00dev, RF_CONTROL3, macvalue);
++                      macvalue = (0x0000F1F1);
++                      rt2800_register_write(rt2x00dev, RF_BYPASS3, macvalue);
++
++                      if (rf_alc_idx == 0) {
++                              rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x21);
++                              for (; vga_gain[ch_idx] > 0;
++                                   vga_gain[ch_idx] = vga_gain[ch_idx] - 2) {
++                                      rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
++                                      rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
++                                      rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
++                                      rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
++                                      rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
++                                      p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
++                                      rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x21);
++                                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
++                                      rt2x00_dbg(rt2x00dev, "LOFT AGC %d %d\n", p0, p1);
++                                      if ((p0 < 7000 * 7000) && (p1 < (7000 * 7000)))
++                                              break;
++                              }
++
++                              rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
++                              rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
++
++                              rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n", vga_gain[ch_idx],
++                                         rfvga_gain_table[vga_gain[ch_idx]]);
++
++                              if (vga_gain[ch_idx] < 0)
++                                      vga_gain[ch_idx] = 0;
++                      }
++
++                      rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
++
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
++
++                      rt2800_loft_search(rt2x00dev, ch_idx, rf_alc_idx, loft_dc_search_result);
++              }
++      }
++
++      for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
++              for (idx = 0; idx < 4; idx++) {
++                      rt2800_bbp_write(rt2x00dev, 158, 0xB0);
++                      bbp = (idx << 2) + rf_alc_idx;
++                      rt2800_bbp_write(rt2x00dev, 159, bbp);
++                      rt2x00_dbg(rt2x00dev, " ALC %2x,", bbp);
++
++                      rt2800_bbp_write(rt2x00dev, 158, 0xb1);
++                      bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x00];
++                      bbp = bbp & 0x3F;
++                      rt2800_bbp_write(rt2x00dev, 159, bbp);
++                      rt2x00_dbg(rt2x00dev, " I0 %2x,", bbp);
++
++                      rt2800_bbp_write(rt2x00dev, 158, 0xb2);
++                      bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x01];
++                      bbp = bbp & 0x3F;
++                      rt2800_bbp_write(rt2x00dev, 159, bbp);
++                      rt2x00_dbg(rt2x00dev, " Q0 %2x,", bbp);
++
++                      rt2800_bbp_write(rt2x00dev, 158, 0xb8);
++                      bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x00];
++                      bbp = bbp & 0x3F;
++                      rt2800_bbp_write(rt2x00dev, 159, bbp);
++                      rt2x00_dbg(rt2x00dev, " I1 %2x,", bbp);
++
++                      rt2800_bbp_write(rt2x00dev, 158, 0xb9);
++                      bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x01];
++                      bbp = bbp & 0x3F;
++                      rt2800_bbp_write(rt2x00dev, 159, bbp);
++                      rt2x00_dbg(rt2x00dev, " Q1 %2x\n", bbp);
++              }
++      }
++
++      rt2800_bbp_write(rt2x00dev, 23, 0x00);
++      rt2800_bbp_write(rt2x00dev, 24, 0x00);
++
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x00);
++      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++
++      bbp = 0x00;
++      rt2800_bbp_write(rt2x00dev, 244, 0x00);
++
++      rt2800_bbp_write(rt2x00dev, 21, 0x01);
++      udelay(1);
++      rt2800_bbp_write(rt2x00dev, 21, 0x00);
++
++      rt2800_rf_configrecover(rt2x00dev, rf_store);
++
++      rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
++      rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
++      udelay(1);
++      rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
++      rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
++      rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
++      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
++      rt2800_register_write(rt2x00dev, RF_CONTROL2, orig528);
++      rt2800_register_write(rt2x00dev, RF_BYPASS2, orig52c);
++      rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
++
++      savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++      macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
++      macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
++      macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
++      macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
++      macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
++
++      bbpr1 = rt2800_bbp_read(rt2x00dev, 1);
++      bbpr4 = rt2800_bbp_read(rt2x00dev, 4);
++      bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
++      bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
++      mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
++
++      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++      macvalue &= (~0x04);
++      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
++              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
++              if (macvalue & 0x01)
++                      usleep_range(50, 100);
++              else
++                      break;
++      }
++
++      macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++      macvalue &= (~0x08);
++      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++      for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
++              macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
++              if (macvalue & 0x02)
++                      usleep_range(50, 100);
++              else
++                      break;
++      }
++
++      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++              rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000101);
++              rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
++      }
++
++      rt2800_bbp_write(rt2x00dev, 23, 0x00);
++      rt2800_bbp_write(rt2x00dev, 24, 0x00);
++
++      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++              rt2800_bbp_write(rt2x00dev, 4, bbpr4 & (~0x18));
++              rt2800_bbp_write(rt2x00dev, 21, 0x01);
++              udelay(1);
++              rt2800_bbp_write(rt2x00dev, 21, 0x00);
++
++              rt2800_bbp_write(rt2x00dev, 241, 0x14);
++              rt2800_bbp_write(rt2x00dev, 242, 0x80);
++              rt2800_bbp_write(rt2x00dev, 244, 0x31);
++      } else {
++              rt2800_setbbptonegenerator(rt2x00dev);
++      }
++
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
++      rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
++      udelay(1);
++
++      rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
++
++      if (!test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++              rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000000);
++              rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
++      }
++
++      rt2800_register_write(rt2x00dev, 0x13b8, 0x00000010);
++
++      for (ch_idx = 0; ch_idx < 2; ch_idx++)
++              rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
++
++      rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x3B);
++      rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x3B);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x03);
++      rt2800_bbp_write(rt2x00dev, 159, 0x60);
++      rt2800_bbp_write(rt2x00dev, 158, 0xB0);
++      rt2800_bbp_write(rt2x00dev, 159, 0x80);
++
++      for (ch_idx = 0; ch_idx < 2; ch_idx++) {
++              rt2800_bbp_write(rt2x00dev, 23, 0x00);
++              rt2800_bbp_write(rt2x00dev, 24, 0x00);
++
++              if (ch_idx == 0) {
++                      rt2800_bbp_write(rt2x00dev, 158, 0x01);
++                      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++                              bbp = bbpr1 & (~0x18);
++                              bbp = bbp | 0x00;
++                              rt2800_bbp_write(rt2x00dev, 1, bbp);
++                      }
++                      rt2800_rf_aux_tx0_loopback(rt2x00dev);
++                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
++              } else {
++                      rt2800_bbp_write(rt2x00dev, 158, 0x01);
++                      rt2800_bbp_write(rt2x00dev, 159, 0x01);
++                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
++                              bbp = bbpr1 & (~0x18);
++                              bbp = bbp | 0x08;
++                              rt2800_bbp_write(rt2x00dev, 1, bbp);
++                      }
++                      rt2800_rf_aux_tx1_loopback(rt2x00dev);
++                      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
++              }
++
++              rt2800_bbp_write(rt2x00dev, 158, 0x05);
++              rt2800_bbp_write(rt2x00dev, 159, 0x04);
++
++              bbp = (ch_idx == 0) ? 0x28 : 0x46;
++              rt2800_bbp_write(rt2x00dev, 158, bbp);
++              rt2800_bbp_write(rt2x00dev, 159, 0x00);
++
++              if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++                      rt2800_bbp_write(rt2x00dev, 23, 0x06);
++                      rt2800_bbp_write(rt2x00dev, 24, 0x06);
++                      count_step = 1;
++              } else {
++                      rt2800_bbp_write(rt2x00dev, 23, 0x1F);
++                      rt2800_bbp_write(rt2x00dev, 24, 0x1F);
++                      count_step = 2;
++              }
++
++              for (; vga_gain[ch_idx] < 19; vga_gain[ch_idx] = (vga_gain[ch_idx] + count_step)) {
++                      rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
++                      rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
++
++                      bbp = (ch_idx == 0) ? 0x29 : 0x47;
++                      rt2800_bbp_write(rt2x00dev, 158, bbp);
++                      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++                      p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
++                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags))
++                              p0_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
++
++                      bbp = (ch_idx == 0) ? 0x29 : 0x47;
++                      rt2800_bbp_write(rt2x00dev, 158, bbp);
++                      rt2800_bbp_write(rt2x00dev, 159, 0x21);
++                      p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
++                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags))
++                              p1_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
++
++                      rt2x00_dbg(rt2x00dev, "IQ AGC %d %d\n", p0, p1);
++
++                      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++                              rt2x00_dbg(rt2x00dev, "IQ AGC IDX 10 %d %d\n", p0_idx10, p1_idx10);
++                              if ((p0_idx10 > 7000 * 7000) || (p1_idx10 > 7000 * 7000)) {
++                                      if (vga_gain[ch_idx] != 0)
++                                              vga_gain[ch_idx] = vga_gain[ch_idx] - 1;
++                                      break;
++                              }
++                      }
++
++                      if ((p0 > 2500 * 2500) || (p1 > 2500 * 2500))
++                              break;
++              }
++
++              if (vga_gain[ch_idx] > 18)
++                      vga_gain[ch_idx] = 18;
++              rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n", vga_gain[ch_idx],
++                         rfvga_gain_table[vga_gain[ch_idx]]);
++
++              bbp = (ch_idx == 0) ? 0x29 : 0x47;
++              rt2800_bbp_write(rt2x00dev, 158, bbp);
++              rt2800_bbp_write(rt2x00dev, 159, 0x00);
++
++              rt2800_iq_search(rt2x00dev, ch_idx, ger, per);
++      }
++
++      rt2800_bbp_write(rt2x00dev, 23, 0x00);
++      rt2800_bbp_write(rt2x00dev, 24, 0x00);
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x28);
++      bbp = ger[CHAIN_0] & 0x0F;
++      rt2800_bbp_write(rt2x00dev, 159, bbp);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x29);
++      bbp = per[CHAIN_0] & 0x3F;
++      rt2800_bbp_write(rt2x00dev, 159, bbp);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x46);
++      bbp = ger[CHAIN_1] & 0x0F;
++      rt2800_bbp_write(rt2x00dev, 159, bbp);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x47);
++      bbp = per[CHAIN_1] & 0x3F;
++      rt2800_bbp_write(rt2x00dev, 159, bbp);
++
++      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++              rt2800_bbp_write(rt2x00dev, 1, bbpr1);
++              rt2800_bbp_write(rt2x00dev, 241, bbpr241);
++              rt2800_bbp_write(rt2x00dev, 242, bbpr242);
++      }
++      rt2800_bbp_write(rt2x00dev, 244, 0x00);
++
++      rt2800_bbp_write(rt2x00dev, 158, 0x00);
++      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++      rt2800_bbp_write(rt2x00dev, 158, 0xB0);
++      rt2800_bbp_write(rt2x00dev, 159, 0x00);
++
++      rt2800_bbp_write(rt2x00dev, 30, bbpr30);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, rfb0r39);
++      rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
++
++      if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags))
++              rt2800_bbp_write(rt2x00dev, 4, bbpr4);
++
++      rt2800_bbp_write(rt2x00dev, 21, 0x01);
++      udelay(1);
++      rt2800_bbp_write(rt2x00dev, 21, 0x00);
++
++      rt2800_rf_configrecover(rt2x00dev, rf_store);
++
++      rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
++      rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
++      rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
++      udelay(1);
++      rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
++      rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
++      rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
++      rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
++      rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
++}
++
+ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
+                                      bool set_bw, bool is_ht40)
+ {
+@@ -9692,6 +10613,7 @@ static void rt2800_init_rfcsr_6352(struc
+       rt2800_rxdcoc_calibration(rt2x00dev);
+       rt2800_bw_filter_calibration(rt2x00dev, true);
+       rt2800_bw_filter_calibration(rt2x00dev, false);
++      rt2800_loft_iq_calibration(rt2x00dev);
+       rt2800_rxiq_calibration(rt2x00dev);
+ }
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -17,6 +17,16 @@
+ #define WCID_START    33
+ #define WCID_END      222
+ #define STA_IDS_SIZE  (WCID_END - WCID_START + 2)
++#define CHAIN_0               0x0
++#define CHAIN_1               0x1
++#define RF_ALC_NUM    6
++#define CHAIN_NUM     2
++
++struct rf_reg_pair {
++      u8 bank;
++      u8 reg;
++      u8 value;
++};
+ /* RT2800 driver data structure */
+ struct rt2800_drv_data {
diff --git a/package/kernel/mac80211/patches/rt2x00/988-rt2x00-move-helper-functions-up-in-file.patch b/package/kernel/mac80211/patches/rt2x00/988-rt2x00-move-helper-functions-up-in-file.patch
new file mode 100644 (file)
index 0000000..7dc37eb
--- /dev/null
@@ -0,0 +1,78 @@
+From f06bc3d756e7bfdaa03f060ae68797321b2e281a Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:22:04 +0100
+Subject: [PATCH 10/16] rt2x00: move helper functions up in file
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+Move register access helper functions up to the head of the file so
+they can be used in all functions.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c    | 40 +++++++++----------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -199,6 +199,26 @@ static void rt2800_rfcsr_write_dccal(str
+       rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value);
+ }
++static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
++                                const u8 reg, const u8 value)
++{
++      rt2800_bbp_write(rt2x00dev, 158, reg);
++      rt2800_bbp_write(rt2x00dev, 159, value);
++}
++
++static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg)
++{
++      rt2800_bbp_write(rt2x00dev, 158, reg);
++      return rt2800_bbp_read(rt2x00dev, 159);
++}
++
++static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
++                                const u8 reg, const u8 value)
++{
++      rt2800_bbp_write(rt2x00dev, 195, reg);
++      rt2800_bbp_write(rt2x00dev, 196, value);
++}
++
+ static u8 rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+                           const unsigned int word)
+ {
+@@ -6955,26 +6975,6 @@ static void rt2800_init_bbp_5592(struct
+               rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+ }
+-static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
+-                                const u8 reg, const u8 value)
+-{
+-      rt2800_bbp_write(rt2x00dev, 195, reg);
+-      rt2800_bbp_write(rt2x00dev, 196, value);
+-}
+-
+-static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
+-                                const u8 reg, const u8 value)
+-{
+-      rt2800_bbp_write(rt2x00dev, 158, reg);
+-      rt2800_bbp_write(rt2x00dev, 159, value);
+-}
+-
+-static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg)
+-{
+-      rt2800_bbp_write(rt2x00dev, 158, reg);
+-      return rt2800_bbp_read(rt2x00dev, 159);
+-}
+-
+ static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev)
+ {
+       u8 bbp;
diff --git a/package/kernel/mac80211/patches/rt2x00/989-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/989-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch
new file mode 100644 (file)
index 0000000..6472bbc
--- /dev/null
@@ -0,0 +1,40 @@
+From d20eadcb4eac59c5168f48c33836fba32b8cd1ae Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:26:03 +0100
+Subject: [PATCH 11/16] rt2x00: fix HT20/HT40 bandwidth switch on MT7620
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+Add missing configuration of the channel bandwidth filter to the
+channel setup function for MT7620.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3814,6 +3814,14 @@ static void rt2800_config_channel_rf7620
+               rfcsr |= tx_agc_fc;
+               rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
+       }
++
++      if (conf_is_ht40(conf)) {
++              rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10);
++              rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f);
++      } else {
++              rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a);
++              rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40);
++      }
+ }
+ static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev,
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
deleted file mode 100644 (file)
index 76114fe..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
---- 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/990-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT762.patch b/package/kernel/mac80211/patches/rt2x00/990-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT762.patch
new file mode 100644 (file)
index 0000000..2ab1cce
--- /dev/null
@@ -0,0 +1,35 @@
+From fa8914fe29543be586e9bbc00c7209e2808f0a13 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:28:40 +0100
+Subject: [PATCH 12/16] rt2x00: set correct TX_SW_CFG1 MAC register for MT7620
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+Set correct TX_SW_CFG1 MAC register as it is done also in v3 of the
+vendor driver[1].
+
+[1]: https://gitlab.com/dm38/padavan-ng/-/blob/master/trunk/proprietary/rt_wifi/rtpci/3.0.X.X/mt76x2/chips/rt6352.c#L531
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -5934,7 +5934,7 @@ static int rt2800_init_registers(struct
+               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_CFG1, 0x000C0001);
+               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);
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
deleted file mode 100644 (file)
index 40b20ec..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
---- 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
-@@ -3698,14 +3698,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,
-@@ -3739,18 +3741,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)) {
-@@ -3850,25 +3857,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);
-@@ -5906,18 +5917,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);
-@@ -7061,14 +7087,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);
-@@ -10407,31 +10435,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);
-@@ -10497,63 +10530,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);
-@@ -10616,12 +10657,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);
diff --git a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/991-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch
new file mode 100644 (file)
index 0000000..4d1700b
--- /dev/null
@@ -0,0 +1,34 @@
+From 5b62ef26e5f17c5cdf19c05e32e2c1da9988480d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:31:15 +0100
+Subject: [PATCH 13/16] rt2x00: set VGC gain for both chains of MT7620
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+Set bbp66 for all chains of the MT7620.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -5711,7 +5711,8 @@ static inline void rt2800_set_vgc(struct
+       if (qual->vgc_level != vgc_level) {
+               if (rt2x00_rt(rt2x00dev, RT3572) ||
+                   rt2x00_rt(rt2x00dev, RT3593) ||
+-                  rt2x00_rt(rt2x00dev, RT3883)) {
++                  rt2x00_rt(rt2x00dev, RT3883) ||
++                  rt2x00_rt(rt2x00dev, RT6352)) {
+                       rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
+                                                      vgc_level);
+               } else if (rt2x00_rt(rt2x00dev, RT5592)) {
diff --git a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-more-fixes.patch b/package/kernel/mac80211/patches/rt2x00/992-rt2x00-more-fixes.patch
deleted file mode 100644 (file)
index 2ad6219..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 12 Sep 2022 21:33:13 +0100
-Subject: [PATCH] rt2x00: various experimental fixes for MT7620
-
-Serge Vasilugin reports:
-
-To improve mt7620 built-in wifi performance some changes:
-1. Correct BW20/BW40 switching (see comments with mark see commets with mark (1))
-2. Correct TX_SW_CFG1 MAC reg from v3 of vendor driver see
-        https://gitlab.com/dm38/padavan-ng/-/blob/master/trunk/proprietary/rt_wifi/rtpci/3.0.X.X/mt76x2/chips/rt6352.c#L531
-3. Set bbp66 for all chains.
-4. US_CYC_CNT init based on Programming guide, default value was 33 (pci),
-   set chipset bus clock with fallback to cpu clock/3.
-5. Don't overwrite default values for mt7620.
-6. Correct some typos.
-7. Add support for external LNA:
-    a) RF and BBP regs never be corrected for this mode
-    b) eLNA is driven the same way as ePA with mt7620's pin PA
-        but vendor driver explicitly pin PA to gpio mode (for forrect calibration?)
-        so I'm not sure that request for pa_pin in dts-file will be enough
-
-First 5 changes (really 2) improve performance for boards w/o eLNA/ePA.
-Changes 7 add support for eLNA
-
-Configuration w/o eLAN/ePA and with eLNA show results
-tx/rx (from router point of view) for each stream:
- 35-40/30-35 Mbps for HT20
- 65-70/60-65 Mbps for HT40
-
-Yes. Max results for 2T2R client is 140-145/135-140
-with peaks 160/150, It correspond to mediatek driver results.
-Boards with ePA untested.
-
-Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -137,6 +137,26 @@ static u8 rt2800_bbp_read(struct rt2x00_
-       return value;
- }
-+//serge: move here for use in test
-+static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
-+                                const u8 reg, const u8 value)
-+{
-+      rt2800_bbp_write(rt2x00dev, 195, reg);
-+      rt2800_bbp_write(rt2x00dev, 196, value);
-+}
-+
-+static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
-+                                const u8 reg, const u8 value)
-+{
-+      rt2800_bbp_write(rt2x00dev, 158, reg);
-+      rt2800_bbp_write(rt2x00dev, 159, value);
-+}
-+
-+static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg)
-+{
-+      rt2800_bbp_write(rt2x00dev, 158, reg);
-+      return rt2800_bbp_read(rt2x00dev, 159);
-+}
- static void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev,
-                              const unsigned int word, const u8 value)
-@@ -284,6 +304,28 @@ static void rt2800_rf_write(struct rt2x0
-       mutex_unlock(&rt2x00dev->csr_mutex);
- }
-+void rt6352_enable_pa_pin(struct rt2x00_dev *rt2x00dev, int enable)
-+{
-+      if (!rt2x00dev->pinctrl)
-+              return;
-+
-+      if (enable) {
-+              if (!rt2x00dev->pins_default) {
-+                      rt2x00_warn(rt2x00dev, "cannot enable PA pin! no default pinctrl\n");
-+                      return;
-+              }
-+
-+              pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_default);
-+      } else {
-+              if (!rt2x00dev->pins_pa_gpio) {
-+                      rt2x00_warn(rt2x00dev, "cannot disable PA pin! no pa_gpio pinctrl\n");
-+                      return;
-+              }
-+
-+              pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_pa_gpio);
-+      }
-+}
-+
- static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
-       [EEPROM_CHIP_ID]                = 0x0000,
-       [EEPROM_VERSION]                = 0x0001,
-@@ -3801,6 +3843,20 @@ static void rt2800_config_channel_rf7620
-               rfcsr |= tx_agc_fc;
-               rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
-       }
-+
-+      if (conf_is_ht40(conf)) {//serge:skipped this step (1)
-+              rt2800_bbp_write(rt2x00dev, 195, 141);
-+              rt2800_bbp_write(rt2x00dev, 196, 0x10);
-+              rt2800_bbp_write(rt2x00dev, 195, 157);
-+              rt2800_bbp_write(rt2x00dev, 196, 0x2f);
-+              //rt2800_bbp_write(rt2x00dev, 105, 0x3C);
-+      } else {
-+              rt2800_bbp_write(rt2x00dev, 195, 141);
-+              rt2800_bbp_write(rt2x00dev, 196, 0x1a);
-+              rt2800_bbp_write(rt2x00dev, 195, 157);
-+              rt2800_bbp_write(rt2x00dev, 196, 0x40);
-+              //rt2800_bbp_write(rt2x00dev, 105, 0x1C);
-+      }
- }
- static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev,
-@@ -4172,6 +4228,11 @@ static void rt2800_config_channel(struct
-                       rt2800_bbp_write(rt2x00dev, 86, 0x46);
-               else
-                       rt2800_bbp_write(rt2x00dev, 86, 0);
-+      } else if (rt2x00_rt(rt2x00dev, RT6352)) {//serge: don't overwite bbp r86 (5)
-+              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, 86, 0x38);
-       } else {
-               rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-               rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-@@ -4377,7 +4438,8 @@ static void rt2800_config_channel(struct
-               reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
-               rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
--              rt2800_iq_calibrate(rt2x00dev, rf->channel);
-+              if (!rt2x00_rt(rt2x00dev, RT6352))//serge: this function for rt5592 only, for rt6352 it switch off compensations (5)
-+                  rt2800_iq_calibrate(rt2x00dev, rf->channel);
-       }
-       if (rt2x00_rt(rt2x00dev, RT6352)) {
-@@ -4417,6 +4479,31 @@ static void rt2800_config_channel(struct
-                       rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
-                                             0x6C6C6B6C);
-               }
-+
-+              if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {//serge: for support eLNA (7a)
-+                      rt2x00_warn(rt2x00dev, "Correct RF/BBP for eLNA!\n");
-+                      reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-+                      reg |= 0x00000101;
-+                      rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
-+
-+                      reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-+                      reg |= 0x00000101;
-+                      rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
-+
-+                      rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
-+                      rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
-+                      rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
-+                      rt2800_bbp_write(rt2x00dev, 75, 0x68);//serge: move bbp eLNA init here?
-+                      rt2800_bbp_write(rt2x00dev, 76, 0x4C);
-+                      rt2800_bbp_write(rt2x00dev, 79, 0x1C);
-+                      rt2800_bbp_write(rt2x00dev, 80, 0x0C);
-+                      rt2800_bbp_write(rt2x00dev, 82, 0xB6);
-+                      /* bank 0 RF reg 42 and glrt BBP reg 141
-+                      will be set in config channel function
-+                      in dependence of channel and HT20/HT40
-+                      so don't touch it
-+                      */
-+              }
-       }
-       bbp = rt2800_bbp_read(rt2x00dev, 4);
-@@ -4457,6 +4544,9 @@ static void rt2800_config_channel(struct
-               rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
-               rt2800_bbp_write(rt2x00dev, 49, bbp);
-       }
-+//serge:just print results after config channel - don't forget to remove nahren (c) <- this is copyright, not ref to comments :)
-+      bbp = rt2800_bbp_dcoc_read(rt2x00dev, 0x03);
-+      pr_info("BBP tx/rx compensation control=0x%02x\n", bbp);
- }
- static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
-@@ -5527,7 +5617,7 @@ void rt2800_vco_calibration(struct rt2x0
-       }
-       rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
--      if (rt2x00_rt(rt2x00dev, RT6352)) {
-+      if (rt2x00_rt(rt2x00dev, RT6352)) {//serge:remark - move all this code to rfcsr_6352 init?
-               if (rt2x00dev->default_ant.rx_chain_num == 1) {
-                       rt2800_bbp_write(rt2x00dev, 91, 0x07);
-                       rt2800_bbp_write(rt2x00dev, 95, 0x1A);
-@@ -5695,7 +5785,8 @@ static inline void rt2800_set_vgc(struct
-       if (qual->vgc_level != vgc_level) {
-               if (rt2x00_rt(rt2x00dev, RT3572) ||
-                   rt2x00_rt(rt2x00dev, RT3593) ||
--                  rt2x00_rt(rt2x00dev, RT3883)) {
-+                  rt2x00_rt(rt2x00dev, RT3883) ||
-+                  rt2x00_rt(rt2x00dev, RT6352)) {//serge: rt6352 too (3)
-                       rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
-                                                      vgc_level);
-               } else if (rt2x00_rt(rt2x00dev, RT5592)) {
-@@ -5930,7 +6021,7 @@ static int rt2800_init_registers(struct
-                                             0x00550055);
-               } else {
-                       rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
--                      rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
-+                      rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001);//serge:was 0x000C0000 (2)
-                       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);
-@@ -6195,6 +6286,29 @@ static int rt2800_init_registers(struct
-               reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
-               rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 125);
-               rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
-+      } else if (rt2x00_is_soc(rt2x00dev)) {//serge:which value correct? (4)
-+              struct clk *clk = clk_get_sys("bus", NULL);
-+              int rate;
-+
-+              if (IS_ERR(clk)) {
-+                      rt2x00_warn(rt2x00dev, "system bus clock undefined\n");
-+                      clk = clk_get_sys("cpu", NULL);
-+
-+                      if (IS_ERR(clk))
-+                          rate = 125;
-+                      else {
-+                          rate = clk_get_rate(clk) / 3000000;
-+                          clk_put(clk);
-+                      }
-+              } else {
-+                      rate = clk_get_rate(clk) / 1000000;
-+                      clk_put(clk);
-+              }
-+
-+              rt2x00_info(rt2x00dev, "set US_CYC=%dMHz\n", rate);
-+              reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
-+              rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, rate);
-+              rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
-       }
-       reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
-@@ -6981,26 +7095,7 @@ static void rt2800_init_bbp_5592(struct
-       if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
-               rt2800_bbp_write(rt2x00dev, 103, 0xc0);
- }
--
--static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
--                                const u8 reg, const u8 value)
--{
--      rt2800_bbp_write(rt2x00dev, 195, reg);
--      rt2800_bbp_write(rt2x00dev, 196, value);
--}
--
--static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
--                                const u8 reg, const u8 value)
--{
--      rt2800_bbp_write(rt2x00dev, 158, reg);
--      rt2800_bbp_write(rt2x00dev, 159, value);
--}
--
--static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg)
--{
--      rt2800_bbp_write(rt2x00dev, 158, reg);
--      return rt2800_bbp_read(rt2x00dev, 159);
--}
-+//serge: move these function upper
- static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev)
- {
-@@ -8635,7 +8730,7 @@ static void rt2800_r_calibration(struct
-               r_cal_code = (u8)rcalcode;
-       rt2800_rfcsr_write_bank(rt2x00dev, 0, 7, r_cal_code);
--
-+      pr_info("RF bank 0 reg 5=0x%02x\n", r_cal_code);//serge: just for info to compare with vendor driver
-       rt2800_bbp_write(rt2x00dev, 22, 0x0);
-       bytevalue = rt2800_bbp_read(rt2x00dev, 21);
-@@ -8693,7 +8788,7 @@ static void rt2800_rxdcoc_calibration(st
-                       break;
-       }
--      saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0);
-+      saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);//serge: was 0 - typo? (6)
-       saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
-       saverfb5r4 = saverfb5r4 & (~0x40);
-       saverfb7r4 = saverfb7r4 & (~0x40);
-@@ -9022,13 +9117,15 @@ static void rt2800_rxiq_calibration(stru
-                               rt2x00_info(rt2x00dev, "RXIQ G_imb=%d, Ph_rx=%d\n", g_imb, ph_rx);
-                               if ((ph_rx > 20) || (ph_rx < -20)) {
-+                                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL(ph_rx=%d out of [-20..20]", ph_rx);//serge:just to see value
-                                       ph_rx = 0;
--                                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-+                                      //rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-                               }
-                               if ((g_imb > 12) || (g_imb < -12)) {
-+                                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL(g_imb=%d out of (-12..12]", g_imb);//serge:just to see the reason
-                                       g_imb = 0;
--                                      rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-+                                      //rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-                               }
-                       }
-               else {
-@@ -9039,11 +9136,21 @@ static void rt2800_rxiq_calibration(stru
-               }
-               if (ch_idx == 0) {
-+                      //serge: just to see values
-+                      pr_info("RXIQ RX0 g_imb (0x37, %2x) ph_rx (0x35, %2x)\n",
-+                          g_imb & 0x3f,
-+                          ph_rx & 0x3f
-+                      );
-                       rt2800_bbp_write(rt2x00dev, 158, 0x37);
-                       rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
-                       rt2800_bbp_write(rt2x00dev, 158, 0x35);
-                       rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
-               } else {
-+                      //serge: just to see values
-+                      pr_info("RXIQ RX1 g_imb (0x55, %2x) ph_rx (0x53, %2x)\n",
-+                          g_imb & 0x3f,
-+                          ph_rx & 0x3f
-+                      );
-                       rt2800_bbp_write(rt2x00dev, 158, 0x55);
-                       rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
-                       rt2800_bbp_write(rt2x00dev, 158, 0x53);
-@@ -9745,6 +9852,15 @@ void rt2800_loft_iq_calibration(struct r
-       }
-       for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
-+              //serge: just to see values
-+              pr_info("LOFT ALC (0xb0, %2x) I0 (0xb1, %2x) Q0 (0xb2, %2x) I1 (0xb8, %2x) Q1 (0xb9, %2x)\n",
-+                  rf_alc_idx,
-+                  loft_dc_search_result[CHAIN_0][rf_alc_idx][0x00] & 0x3F,
-+                  loft_dc_search_result[CHAIN_0][rf_alc_idx][0x01] & 0x3F,
-+                  loft_dc_search_result[CHAIN_1][rf_alc_idx][0x00] & 0x3F,
-+                  loft_dc_search_result[CHAIN_1][rf_alc_idx][0x01] & 0x3F
-+              );
-+
-               for (idx = 0; idx < 4; idx++) {
-                       rt2800_bbp_write(rt2x00dev, 158, 0xB0);
-                       bbp = (idx<<2) + rf_alc_idx;
-@@ -10669,6 +10785,7 @@ static void rt2800_init_rfcsr_6352(struc
-               rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
-       }
-+      rt6352_enable_pa_pin(rt2x00dev, 0);//serge: vendor driver do it before calibration (7b)
-       rt2800_r_calibration(rt2x00dev);
-       rt2800_rf_self_txdc_cal(rt2x00dev);
-       rt2800_rxdcoc_calibration(rt2x00dev);
-@@ -10676,6 +10793,29 @@ static void rt2800_init_rfcsr_6352(struc
-       rt2800_bw_filter_calibration(rt2x00dev, false);
-       rt2800_loft_iq_calibration(rt2x00dev);
-       rt2800_rxiq_calibration(rt2x00dev);
-+      rt6352_enable_pa_pin(rt2x00dev, 1);//serge: vendor driver do it after calibration (7b)
-+      /* Vendor driver restore iLNA/iPA before
-+      recalibration and set correct values after.
-+      Openwrt driver init iLNA and iPA but restore only
-+      ePA values after recalibration.
-+      So set eLNA values only
-+      */
-+      if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {//serge: rf regs never corrected for eLNA (7a)
-+              rt2x00_info(rt2x00dev, "Correct RF/BBP for eLNA!\n");
-+              rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
-+              rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
-+              rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
-+              rt2800_bbp_write(rt2x00dev, 75, 0x68);//serge: move bbp eLNA init here?
-+              rt2800_bbp_write(rt2x00dev, 76, 0x4C);
-+              rt2800_bbp_write(rt2x00dev, 79, 0x1C);
-+              rt2800_bbp_write(rt2x00dev, 80, 0x0C);
-+              rt2800_bbp_write(rt2x00dev, 82, 0xB6);
-+              /* bank 0 RF reg 42 and glrt BBP reg 141
-+              will be set in config channel function
-+              in dependence of channel and HT20/HT40
-+              so don't touch it
-+              */
-+      }
- }
- static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -28,6 +28,7 @@
- #include <linux/average.h>
- #include <linux/usb.h>
- #include <linux/clk.h>
-+#include <linux/pinctrl/consumer.h>
- #include <linux/rt2x00_platform.h>
- #include <net/mac80211.h>
-@@ -1029,6 +1030,11 @@ struct rt2x00_dev {
-       /* Clock for System On Chip devices. */
-       struct clk *clk;
-+
-+      /* pinctrl and states for System On Chip devices with PA/LNA. */
-+      struct pinctrl *pinctrl;
-+      struct pinctrl_state *pins_default;
-+      struct pinctrl_state *pins_pa_gpio;
- };
- struct rt2x00_bar_list_entry {
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
-@@ -97,6 +97,21 @@ int rt2x00soc_probe(struct platform_devi
-       if (retval)
-               goto exit_free_reg;
-+      rt2x00dev->pinctrl = devm_pinctrl_get(&pdev->dev);
-+      if (IS_ERR(rt2x00dev->pinctrl)) {
-+              rt2x00dev->pinctrl = NULL;
-+              rt2x00dev->pins_default = NULL;
-+              rt2x00dev->pins_pa_gpio = NULL;
-+      } else {
-+              rt2x00dev->pins_default = pinctrl_lookup_state(rt2x00dev->pinctrl, "default");
-+              if (IS_ERR(rt2x00dev->pins_default))
-+                      rt2x00dev->pins_default = NULL;
-+
-+              rt2x00dev->pins_pa_gpio = pinctrl_lookup_state(rt2x00dev->pinctrl, "pa_gpio");
-+              if (IS_ERR(rt2x00dev->pins_pa_gpio))
-+                      rt2x00dev->pins_pa_gpio = NULL;
-+      }
-+
-       return 0;
- exit_free_reg:
diff --git a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-set-SoC-wmac-clock-register.patch b/package/kernel/mac80211/patches/rt2x00/992-rt2x00-set-SoC-wmac-clock-register.patch
new file mode 100644 (file)
index 0000000..194d7d6
--- /dev/null
@@ -0,0 +1,54 @@
+From 6569ed4ba88105d7ee877abba8f22e4965a29856 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:38:20 +0100
+Subject: [PATCH 14/16] rt2x00: set SoC wmac clock register
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+Instead of using the default value 33 (pci), set US_CYC_CNT init based
+on Programming guide:
+If available, set chipset bus clock with fallback to cpu clock/3.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c    | 21 +++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -6197,6 +6197,27 @@ static int rt2800_init_registers(struct
+               reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
+               rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 125);
+               rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
++      } else if (rt2x00_is_soc(rt2x00dev)) {
++              struct clk *clk = clk_get_sys("bus", NULL);
++              int rate;
++
++              if (IS_ERR(clk)) {
++                      clk = clk_get_sys("cpu", NULL);
++
++                      if (IS_ERR(clk)) {
++                              rate = 125;
++                      } else {
++                              rate = clk_get_rate(clk) / 3000000;
++                              clk_put(clk);
++                      }
++              } else {
++                      rate = clk_get_rate(clk) / 1000000;
++                      clk_put(clk);
++              }
++
++              reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
++              rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, rate);
++              rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
+       }
+       reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
diff --git a/package/kernel/mac80211/patches/rt2x00/993-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/993-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch
new file mode 100644 (file)
index 0000000..0b673bc
--- /dev/null
@@ -0,0 +1,36 @@
+From 3ae108de9e64e44c724ce150d804c56a4e72ea4e Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:42:11 +0100
+Subject: [PATCH 15/16] rt2x00: correctly set BBP register 86 for MT7620
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+Instead of 0 set the correct value for BBP register 86 for MT7620.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -4193,7 +4193,10 @@ static void rt2800_config_channel(struct
+               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, 86, 0);
++              if (rt2x00_rt(rt2x00dev, RT6352))
++                      rt2800_bbp_write(rt2x00dev, 86, 0x38);
++              else
++                      rt2800_bbp_write(rt2x00dev, 86, 0);
+       }
+       if (rf->channel <= 14) {
diff --git a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch
new file mode 100644 (file)
index 0000000..3d5849b
--- /dev/null
@@ -0,0 +1,161 @@
+From 0fce1109f894ec7fcd72cb098843a1eff786716a Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 16 Sep 2022 20:49:42 +0100
+Subject: [PATCH 16/16] rt2x00: import support for external LNA on MT7620
+To: linux-wireless@vger.kernel.org,
+    Stanislaw Gruszka <stf_xl@wp.pl>,
+    Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@kernel.org>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Johannes Berg <johannes.berg@intel.com>
+
+In order to carry out calibration on boards with ePA or eLNA the PA pin
+needs to be switch to GPIO mode on MT7620. Implement that by selecting
+pinctrl state "pa_gpio" which should be defined for MT7620 boards with
+eLNA or ePA beside the "default" state.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c    | 58 +++++++++++++++++++
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h   |  5 ++
+ .../net/wireless/ralink/rt2x00/rt2x00soc.c    | 15 +++++
+ 3 files changed, 78 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -304,6 +304,24 @@ static void rt2800_rf_write(struct rt2x0
+       mutex_unlock(&rt2x00dev->csr_mutex);
+ }
++void rt6352_enable_pa_pin(struct rt2x00_dev *rt2x00dev, int enable)
++{
++      if (!rt2x00dev->pinctrl)
++              return;
++
++      if (enable) {
++              if (!rt2x00dev->pins_default)
++                      return;
++
++              pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_default);
++      } else {
++              if (!rt2x00dev->pins_pa_gpio)
++                      return;
++
++              pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_pa_gpio);
++      }
++}
++
+ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
+       [EEPROM_CHIP_ID]                = 0x0000,
+       [EEPROM_VERSION]                = 0x0001,
+@@ -4436,6 +4454,29 @@ static void rt2800_config_channel(struct
+                       rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
+                                             0x6C6C6B6C);
+               }
++
++              if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
++                      reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
++                      reg |= 0x00000101;
++                      rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
++
++                      reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
++                      reg |= 0x00000101;
++                      rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
++
++                      rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
++                      rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
++                      rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
++                      rt2800_bbp_write(rt2x00dev, 75, 0x68);
++                      rt2800_bbp_write(rt2x00dev, 76, 0x4C);
++                      rt2800_bbp_write(rt2x00dev, 79, 0x1C);
++                      rt2800_bbp_write(rt2x00dev, 80, 0x0C);
++                      rt2800_bbp_write(rt2x00dev, 82, 0xB6);
++                      /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in
++                       * config channel function in dependence of channel and
++                       * HT20/HT40 so don't touch it
++                       */
++              }
+       }
+       bbp = rt2800_bbp_read(rt2x00dev, 4);
+@@ -10641,6 +10682,7 @@ static void rt2800_init_rfcsr_6352(struc
+       rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
+       rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
++      rt6352_enable_pa_pin(rt2x00dev, 0);
+       rt2800_r_calibration(rt2x00dev);
+       rt2800_rf_self_txdc_cal(rt2x00dev);
+       rt2800_rxdcoc_calibration(rt2x00dev);
+@@ -10648,6 +10690,22 @@ static void rt2800_init_rfcsr_6352(struc
+       rt2800_bw_filter_calibration(rt2x00dev, false);
+       rt2800_loft_iq_calibration(rt2x00dev);
+       rt2800_rxiq_calibration(rt2x00dev);
++      rt6352_enable_pa_pin(rt2x00dev, 1);
++
++      if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
++              rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
++              rt2800_bbp_write(rt2x00dev, 75, 0x68);
++              rt2800_bbp_write(rt2x00dev, 76, 0x4C);
++              rt2800_bbp_write(rt2x00dev, 79, 0x1C);
++              rt2800_bbp_write(rt2x00dev, 80, 0x0C);
++              rt2800_bbp_write(rt2x00dev, 82, 0xB6);
++              /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config
++               * channel function in dependence of channel and HT20/HT40,
++               * so don't touch them here.
++               */
++      }
+ }
+ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -28,6 +28,7 @@
+ #include <linux/average.h>
+ #include <linux/usb.h>
+ #include <linux/clk.h>
++#include <linux/pinctrl/consumer.h>
+ #include <linux/rt2x00_platform.h>
+ #include <net/mac80211.h>
+@@ -1029,6 +1030,11 @@ struct rt2x00_dev {
+       /* Clock for System On Chip devices. */
+       struct clk *clk;
++
++      /* pinctrl and states for System On Chip devices with PA/LNA. */
++      struct pinctrl *pinctrl;
++      struct pinctrl_state *pins_default;
++      struct pinctrl_state *pins_pa_gpio;
+ };
+ struct rt2x00_bar_list_entry {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
+@@ -97,6 +97,21 @@ int rt2x00soc_probe(struct platform_devi
+       if (retval)
+               goto exit_free_reg;
++      rt2x00dev->pinctrl = devm_pinctrl_get(&pdev->dev);
++      if (IS_ERR(rt2x00dev->pinctrl)) {
++              rt2x00dev->pinctrl = NULL;
++              rt2x00dev->pins_default = NULL;
++              rt2x00dev->pins_pa_gpio = NULL;
++      } else {
++              rt2x00dev->pins_default = pinctrl_lookup_state(rt2x00dev->pinctrl, "default");
++              if (IS_ERR(rt2x00dev->pins_default))
++                      rt2x00dev->pins_default = NULL;
++
++              rt2x00dev->pins_pa_gpio = pinctrl_lookup_state(rt2x00dev->pinctrl, "pa_gpio");
++              if (IS_ERR(rt2x00dev->pins_pa_gpio))
++                      rt2x00dev->pins_pa_gpio = NULL;
++      }
++
+       return 0;
+ exit_free_reg:
diff --git a/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch b/package/kernel/mac80211/patches/rt2x00/995-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/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch
new file mode 100644 (file)
index 0000000..de09186
--- /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
+@@ -3736,14 +3736,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,
+@@ -3777,18 +3779,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)) {
+@@ -3896,25 +3903,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);
+@@ -5978,18 +5989,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, 0x000C0001);
+-              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, 0x000C0001);
++                      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);
+@@ -7134,14 +7160,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);
+@@ -10466,31 +10494,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);
+@@ -10556,63 +10589,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);
+@@ -10675,12 +10716,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);
++      }
+       rt6352_enable_pa_pin(rt2x00dev, 0);
+       rt2800_r_calibration(rt2x00dev);