--- /dev/null
+From patchwork Sat Sep 17 20:26:27 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979242
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:26:27 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 01/16] rt2x00: define RF5592 in init_eeprom routine
+Message-ID:
+ <d7eccb2c7b8ec4cd360fa2007796abffc35abb0d.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
+
+Fix incorrect RF value encoded in EEPROM on devices with Ralink Rt5592
+PCIe radio (a single chip 2T2R 802.11abgn solution).
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -9435,6 +9435,8 @@ static int rt2800_init_eeprom(struct rt2
+ rf = RF3853;
+ else if (rt2x00_rt(rt2x00dev, RT5350))
+ rf = RF5350;
++ else if (rt2x00_rt(rt2x00dev, RT5592))
++ rf = RF5592;
+ else
+ rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+
--- /dev/null
+From patchwork Sat Sep 17 20:26:40 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979243
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:26:40 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 02/16] rt2x00: add throughput LED trigger
+Message-ID:
+ <73f5ba4134e621462a26186449400cf0c1ac1730.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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.
+
+Tested-by: Christoph Krapp <achterin@googlemail.com>
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -1093,6 +1093,19 @@ static void rt2x00lib_remove_hw(struct r
+ kfree(rt2x00dev->spec.channels_info);
+ }
+
++static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
++ { .throughput = 0 * 1024, .blink_time = 334 },
++ { .throughput = 1 * 1024, .blink_time = 260 },
++ { .throughput = 2 * 1024, .blink_time = 220 },
++ { .throughput = 5 * 1024, .blink_time = 190 },
++ { .throughput = 10 * 1024, .blink_time = 170 },
++ { .throughput = 25 * 1024, .blink_time = 150 },
++ { .throughput = 54 * 1024, .blink_time = 130 },
++ { .throughput = 120 * 1024, .blink_time = 110 },
++ { .throughput = 265 * 1024, .blink_time = 80 },
++ { .throughput = 586 * 1024, .blink_time = 50 },
++};
++
+ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
+ {
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
+@@ -1174,6 +1187,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));
++
+ /*
+ * Register HW.
+ */
+++ /dev/null
-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
-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>
-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
-
-This patch fixes following crash on Linksys EA2750 during 5GHz wifi
-init:
-
-[ 7.955153] rt2800pci 0000:01:00.0: card - bus=0x1, slot = 0x0 irq=4
-[ 7.962259] rt2800pci 0000:01:00.0: loaded eeprom from mtd device "Factory"
-[ 7.969435] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 5592, rev 0222 detected
-[ 7.977348] ieee80211 phy0: rt2800_init_eeprom: Error - Invalid RF chipset 0x0000 detected
-[ 7.985793] ieee80211 phy0: rt2x00lib_probe_dev: Error - Failed to allocate device
-[ 7.993569] CPU 0 Unable to handle kernel paging request at virtual address 00000024, epc == 800c8f54, ra == 80249ff8
-[ 8.004408] Oops[#1]:
-
-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(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -9435,6 +9435,8 @@ static int rt2800_init_eeprom(struct rt2
- rf = RF3853;
- else if (rt2x00_rt(rt2x00dev, RT5350))
- rf = RF5350;
-+ else if (rt2x00_rt(rt2x00dev, RT5592))
-+ rf = RF5592;
- else
- rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
-
--- /dev/null
+From patchwork Sat Sep 17 20:26:55 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979244
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:26:55 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 03/16] rt2x00: add support for external PA on MT7620
+Message-ID:
+ <af2c68ff831816a86fc39b0c10911c129a1f03dc.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -2739,6 +2739,7 @@ enum rt2800_eeprom_word {
+ #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(0x8000)
+
+ /*
+ * EEPROM LNA
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -4368,6 +4368,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)) {
++ 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, 43, 0x73);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
++
++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
++ 0x36303636);
++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
++ 0x6C6C6B6C);
++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
++ 0x6C6C6B6C);
++ }
++ }
++
+ bbp = rt2800_bbp_read(rt2x00dev, 4);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
+ rt2800_bbp_write(rt2x00dev, 4, bbp);
+@@ -9566,7 +9603,8 @@ static int rt2800_init_eeprom(struct rt2
+ */
+ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
+
+- if (rt2x00_rt(rt2x00dev, RT3352)) {
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT6352)) {
+ if (rt2x00_get_field16(eeprom,
+ EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
+@@ -9577,6 +9615,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)) {
++ __clear_bit(CAPABILITY_EXTERNAL_PA_TX0,
++ &rt2x00dev->cap_flags);
++ __clear_bit(CAPABILITY_EXTERNAL_PA_TX1,
++ &rt2x00dev->cap_flags);
++ }
++ }
++
+ return 0;
+ }
+
--- /dev/null
+From patchwork Sat Sep 17 20:27:10 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979245
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:27:10 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 04/16] rt2x00: move up and reuse busy wait functions
+Message-ID:
+ <3fdb9dc15e76a9f9c1948b4a3a1308a7a5677bb8.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+Move bbp_ready and rf_ready busy wait functions up in the code so they
+can more easily be used. Allow specifying register mask in rf_ready
+function which is useful for calibration routines which will be added
+in follow-up commits.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 99 +++++++++----------
+ 1 file changed, 46 insertions(+), 53 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -2143,6 +2143,48 @@ void rt2800_config_erp(struct rt2x00_dev
+ }
+ EXPORT_SYMBOL_GPL(rt2800_config_erp);
+
++static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev,
++ const struct rt2x00_field32 mask)
++{
++ unsigned int i;
++ u32 reg;
++
++ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
++ reg = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
++ if (!rt2x00_get_field32(reg, mask))
++ return 0;
++
++ udelay(REGISTER_BUSY_DELAY);
++ }
++
++ rt2x00_err(rt2x00dev, "BBP/RF register access failed, aborting\n");
++ return -EACCES;
++}
++
++static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
++{
++ unsigned int i;
++ u8 value;
++
++ /*
++ * BBP was enabled after firmware was loaded,
++ * but we need to reactivate it now.
++ */
++ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
++ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
++ msleep(1);
++
++ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
++ value = rt2800_bbp_read(rt2x00dev, 0);
++ if ((value != 0xff) && (value != 0x00))
++ return 0;
++ udelay(REGISTER_BUSY_DELAY);
++ }
++
++ rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n");
++ return -EACCES;
++}
++
+ static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
+ {
+ u32 reg;
+@@ -3799,10 +3841,9 @@ static void rt2800_config_alc(struct rt2
+ struct ieee80211_channel *chan,
+ int power_level) {
+ u16 eeprom, target_power, max_power;
+- u32 mac_sys_ctrl, mac_status;
++ u32 mac_sys_ctrl;
+ u32 reg;
+ u8 bbp;
+- int i;
+
+ /* hardware unit is 0.5dBm, limited to 23.5dBm */
+ power_level *= 2;
+@@ -3838,16 +3879,8 @@ static void rt2800_config_alc(struct rt2
+ /* Disable Tx/Rx */
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
+ /* Check MAC Tx/Rx idle */
+- for (i = 0; i < 10000; i++) {
+- mac_status = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
+- if (mac_status & 0x3)
+- usleep_range(50, 200);
+- else
+- break;
+- }
+-
+- if (i == 10000)
+- rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY)))
++ rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n");
+
+ if (chan->center_freq > 2457) {
+ bbp = rt2800_bbp_read(rt2x00dev, 30);
+@@ -6249,46 +6282,6 @@ static int rt2800_init_registers(struct
+ return 0;
+ }
+
+-static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
+-{
+- unsigned int i;
+- u32 reg;
+-
+- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+- reg = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
+- if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
+- return 0;
+-
+- udelay(REGISTER_BUSY_DELAY);
+- }
+-
+- rt2x00_err(rt2x00dev, "BBP/RF register access failed, aborting\n");
+- return -EACCES;
+-}
+-
+-static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
+-{
+- unsigned int i;
+- u8 value;
+-
+- /*
+- * BBP was enabled after firmware was loaded,
+- * but we need to reactivate it now.
+- */
+- rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+- msleep(1);
+-
+- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+- value = rt2800_bbp_read(rt2x00dev, 0);
+- if ((value != 0xff) && (value != 0x00))
+- return 0;
+- udelay(REGISTER_BUSY_DELAY);
+- }
+-
+- rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n");
+- return -EACCES;
+-}
+
+ static void rt2800_bbp4_mac_if_ctrl(struct rt2x00_dev *rt2x00dev)
+ {
+@@ -9110,7 +9103,7 @@ int rt2800_enable_radio(struct rt2x00_de
+ /*
+ * Wait BBP/RF to wake up.
+ */
+- if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev)))
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY)))
+ return -EIO;
+
+ /*
--- /dev/null
+From patchwork Sat Sep 17 20:27:26 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979246
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:27:26 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 05/16] rt2x00: add RF self TXDC calibration for MT7620
+Message-ID:
+ <dbb6e5a0c12d6101477bd09e83253091d21512c9.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+v2: use ++i instead of i = i + 1 in loops
+
+ .../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
+@@ -8428,6 +8428,53 @@ static void rt2800_init_rfcsr_5592(struc
+ rt2800_led_open_drain_enable(rt2x00dev);
+ }
+
++static void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev)
++{
++ u8 rfb5r1_org, rfb7r1_org, rfvalue;
++ u32 mac0518, mac051c, mac0528, mac052c;
++ u8 i;
++
++ mac0518 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
++ mac051c = rt2800_register_read(rt2x00dev, RF_BYPASS0);
++ mac0528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
++ mac052c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
++
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
++ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0xC);
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x3306);
++ rt2800_register_write(rt2x00dev, RF_CONTROL2, 0x3330);
++ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0xfffff);
++ rfb5r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
++ rfb7r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, 0x4);
++ for (i = 0; i < 100; ++i) {
++ usleep_range(50, 100);
++ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
++ 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) {
++ usleep_range(50, 100);
++ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
++ if ((rfvalue & 0x04) != 0x4)
++ break;
++ }
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, rfb7r1_org);
++
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
++ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, mac0518);
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, mac051c);
++ rt2800_register_write(rt2x00dev, RF_CONTROL2, mac0528);
++ rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c);
++}
++
+ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
+ bool set_bw, bool is_ht40)
+ {
+@@ -9035,6 +9082,7 @@ static void rt2800_init_rfcsr_6352(struc
+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
+
++ rt2800_rf_self_txdc_cal(rt2x00dev);
+ rt2800_bw_filter_calibration(rt2x00dev, true);
+ rt2800_bw_filter_calibration(rt2x00dev, false);
+ }
--- /dev/null
+From patchwork Sat Sep 17 20:27:41 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979247
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:27:41 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 06/16] rt2x00: add r calibration for MT7620
+Message-ID:
+ <e0c34f233089bec4eb73826bc4f512166ee25934.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
+
+Add r calibration code as found in mtk driver.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+v2: use rt2800_wait_bbp_rf_ready()
+
+ drivers/net/wireless/ralink/rt2x00/rt2800.h | 2 +
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 133 ++++++++++++++++++
+ 2 files changed, 135 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -1016,6 +1016,8 @@
+ */
+ #define MAC_STATUS_CFG 0x1200
+ #define MAC_STATUS_CFG_BBP_RF_BUSY FIELD32(0x00000003)
++#define MAC_STATUS_CFG_BBP_RF_BUSY_TX FIELD32(0x00000001)
++#define MAC_STATUS_CFG_BBP_RF_BUSY_RX FIELD32(0x00000002)
+
+ /*
+ * PWR_PIN_CFG:
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -8475,6 +8475,138 @@ 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 = ((d2 - d1) * 1000) / 43;
++
++ if ((calcode % 10) >= 5)
++ calcode += 10;
++ calcode = (calcode / 10);
++
++ return calcode;
++}
++
++static void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev)
++{
++ u32 savemacsysctrl;
++ u8 saverfb0r1, saverfb0r34, saverfb0r35;
++ u8 saverfb5r4, saverfb5r17, saverfb5r18;
++ u8 saverfb5r19, saverfb5r20;
++ u8 savebbpr22, savebbpr47, savebbpr49;
++ u8 bytevalue = 0;
++ int rcalcode;
++ u8 r_cal_code = 0;
++ char d1 = 0, d2 = 0;
++ u8 rfvalue;
++ u32 MAC_RF_BYPASS0, MAC_RF_CONTROL0, MAC_PWR_PIN_CFG;
++ u32 maccfg;
++
++ saverfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
++ saverfb0r34 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 34);
++ saverfb0r35 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
++ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
++ saverfb5r17 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
++ saverfb5r18 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
++ saverfb5r19 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
++ saverfb5r20 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
++
++ savebbpr22 = rt2800_bbp_read(rt2x00dev, 22);
++ savebbpr47 = rt2800_bbp_read(rt2x00dev, 47);
++ savebbpr49 = rt2800_bbp_read(rt2x00dev, 49);
++
++ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ MAC_RF_BYPASS0 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
++ MAC_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
++ MAC_PWR_PIN_CFG = rt2800_register_read(rt2x00dev, PWR_PIN_CFG);
++
++ maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ maccfg &= (~0x04);
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX)))
++ rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n");
++
++ maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ maccfg &= (~0x04);
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX)))
++ rt2x00_warn(rt2x00dev, "Wait MAC Rx Status to MAX !!!\n");
++
++ rfvalue = (MAC_RF_BYPASS0 | 0x3004);
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, rfvalue);
++ rfvalue = (MAC_RF_CONTROL0 | (~0x3002));
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, rfvalue);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, 0x27);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, 0x80);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0x83);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x00);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x20);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x00);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 34, 0x13);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
++
++ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x1);
++
++ rt2800_bbp_write(rt2x00dev, 47, 0x04);
++ rt2800_bbp_write(rt2x00dev, 22, 0x80);
++ usleep_range(100, 200);
++ bytevalue = rt2800_bbp_read(rt2x00dev, 49);
++ if (bytevalue > 128)
++ d1 = bytevalue - 256;
++ else
++ d1 = (char)bytevalue;
++ rt2800_bbp_write(rt2x00dev, 22, 0x0);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x01);
++
++ rt2800_bbp_write(rt2x00dev, 22, 0x80);
++ usleep_range(100, 200);
++ bytevalue = rt2800_bbp_read(rt2x00dev, 49);
++ if (bytevalue > 128)
++ d2 = bytevalue - 256;
++ else
++ d2 = (char)bytevalue;
++ rt2800_bbp_write(rt2x00dev, 22, 0x0);
++
++ rcalcode = rt2800_calcrcalibrationcode(rt2x00dev, d1, d2);
++ if (rcalcode < 0)
++ r_cal_code = 256 + rcalcode;
++ else
++ r_cal_code = (u8)rcalcode;
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 7, r_cal_code);
++
++ rt2800_bbp_write(rt2x00dev, 22, 0x0);
++
++ bytevalue = rt2800_bbp_read(rt2x00dev, 21);
++ bytevalue |= 0x1;
++ rt2800_bbp_write(rt2x00dev, 21, bytevalue);
++ bytevalue = rt2800_bbp_read(rt2x00dev, 21);
++ bytevalue &= (~0x1);
++ rt2800_bbp_write(rt2x00dev, 21, bytevalue);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, saverfb0r1);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 34, saverfb0r34);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, saverfb0r35);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, saverfb5r17);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, saverfb5r18);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, saverfb5r19);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, saverfb5r20);
++
++ rt2800_bbp_write(rt2x00dev, 22, savebbpr22);
++ rt2800_bbp_write(rt2x00dev, 47, savebbpr47);
++ rt2800_bbp_write(rt2x00dev, 49, savebbpr49);
++
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0);
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, MAC_RF_CONTROL0);
++
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
++ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
++}
++
+ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
+ bool set_bw, bool is_ht40)
+ {
+@@ -9082,6 +9214,7 @@ static void rt2800_init_rfcsr_6352(struc
+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
+
++ rt2800_r_calibration(rt2x00dev);
+ rt2800_rf_self_txdc_cal(rt2x00dev);
+ rt2800_bw_filter_calibration(rt2x00dev, true);
+ rt2800_bw_filter_calibration(rt2x00dev, false);
--- /dev/null
+From patchwork Sat Sep 17 20:27:56 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979248
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:27:56 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 07/16] rt2x00: add RXDCOC calibration for MT7620
+Message-ID:
+ <850b30f652e88de30d79e968af4eb47aa5bc2511.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
+
+Add RXDCOC calibration code from mtk driver.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+[fixed typo reported by Serge Vasilugin <vasilugin@yandex.ru>]
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 60 +++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -8607,6 +8607,65 @@ static void rt2800_r_calibration(struct
+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
+ }
+
++static void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev)
++{
++ u8 bbpreg = 0;
++ u32 macvalue = 0;
++ u8 saverfb0r2, saverfb5r4, saverfb7r4, rfvalue;
++ int i;
++
++ saverfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
++ rfvalue = saverfb0r2;
++ rfvalue |= 0x03;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfvalue);
++
++ rt2800_bbp_write(rt2x00dev, 158, 141);
++ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
++ bbpreg |= 0x10;
++ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
++
++ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x8);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX)))
++ rt2x00_warn(rt2x00dev, "RF TX busy in RX RXDCOC calibration\n");
++
++ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
++ saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
++ saverfb5r4 = saverfb5r4 & (~0x40);
++ saverfb7r4 = saverfb7r4 & (~0x40);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x64);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4);
++
++ rt2800_bbp_write(rt2x00dev, 158, 141);
++ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
++ bbpreg = bbpreg & (~0x40);
++ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
++ bbpreg |= 0x48;
++ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
++
++ for (i = 0; i < 10000; i++) {
++ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
++ if ((bbpreg & 0x40) == 0)
++ break;
++ usleep_range(50, 100);
++ }
++
++ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
++ bbpreg = bbpreg & (~0x40);
++ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
++
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++
++ rt2800_bbp_write(rt2x00dev, 158, 141);
++ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
++ bbpreg &= (~0x10);
++ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
++}
++
+ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
+ bool set_bw, bool is_ht40)
+ {
+@@ -9216,6 +9275,7 @@ static void rt2800_init_rfcsr_6352(struc
+
+ rt2800_r_calibration(rt2x00dev);
+ rt2800_rf_self_txdc_cal(rt2x00dev);
++ rt2800_rxdcoc_calibration(rt2x00dev);
+ rt2800_bw_filter_calibration(rt2x00dev, true);
+ rt2800_bw_filter_calibration(rt2x00dev, false);
+ }
--- /dev/null
+From patchwork Sat Sep 17 20:28:10 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979249
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:28:10 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 08/16] rt2x00: add RXIQ calibration for MT7620
+Message-ID:
+ <033a39a697d51f6df258acea4c33608e0944fe4c.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+v2: use rt2800_wait_bbp_rf_ready(), fix indentation
+
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 375 ++++++++++++++++++
+ 1 file changed, 375 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -8666,6 +8666,380 @@ static void rt2800_rxdcoc_calibration(st
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
+ }
+
++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)
++ root = root_pre;
++ bit = bit >> 1;
++ }
++
++ return root;
++}
++
++static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev)
++{
++ u8 rfb0r1, rfb0r2, rfb0r42;
++ u8 rfb4r0, rfb4r19;
++ u8 rfb5r3, rfb5r4, rfb5r17, rfb5r18, rfb5r19, rfb5r20;
++ u8 rfb6r0, rfb6r19;
++ u8 rfb7r3, rfb7r4, rfb7r17, rfb7r18, rfb7r19, rfb7r20;
++
++ u8 bbp1, bbp4;
++ u8 bbpr241, bbpr242;
++ u32 i;
++ u8 ch_idx;
++ u8 bbpval;
++ u8 rfval, vga_idx = 0;
++ int mi = 0, mq = 0, si = 0, sq = 0, riq = 0;
++ int sigma_i, sigma_q, r_iq, g_rx;
++ int g_imb;
++ int ph_rx;
++ u32 savemacsysctrl = 0;
++ u32 orig_RF_CONTROL0 = 0;
++ u32 orig_RF_BYPASS0 = 0;
++ u32 orig_RF_CONTROL1 = 0;
++ u32 orig_RF_BYPASS1 = 0;
++ u32 orig_RF_CONTROL3 = 0;
++ u32 orig_RF_BYPASS3 = 0;
++ u32 bbpval1 = 0;
++ static const u8 rf_vga_table[] = {0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
++
++ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ orig_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
++ orig_RF_BYPASS0 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
++ orig_RF_CONTROL1 = rt2800_register_read(rt2x00dev, RF_CONTROL1);
++ orig_RF_BYPASS1 = rt2800_register_read(rt2x00dev, RF_BYPASS1);
++ orig_RF_CONTROL3 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
++ orig_RF_BYPASS3 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
++
++ bbp1 = rt2800_bbp_read(rt2x00dev, 1);
++ bbp4 = rt2800_bbp_read(rt2x00dev, 4);
++
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x0);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY)))
++ rt2x00_warn(rt2x00dev, "Timeout waiting for MAC status in RXIQ calibration\n");
++
++ bbpval = bbp4 & (~0x18);
++ bbpval = bbp4 | 0x00;
++ rt2800_bbp_write(rt2x00dev, 4, bbpval);
++
++ bbpval = rt2800_bbp_read(rt2x00dev, 21);
++ bbpval = bbpval | 1;
++ rt2800_bbp_write(rt2x00dev, 21, bbpval);
++ bbpval = bbpval & 0xfe;
++ rt2800_bbp_write(rt2x00dev, 21, bbpval);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL1, 0x00000202);
++ rt2800_register_write(rt2x00dev, RF_BYPASS1, 0x00000303);
++ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags))
++ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0101);
++ else
++ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0000);
++
++ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0xf1f1);
++
++ rfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
++ rfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
++ rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
++ rfb4r0 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
++ rfb4r19 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 19);
++ rfb5r3 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
++ rfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
++ rfb5r17 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
++ rfb5r18 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
++ rfb5r19 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
++ rfb5r20 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
++
++ rfb6r0 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
++ rfb6r19 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 19);
++ rfb7r3 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
++ rfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
++ rfb7r17 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
++ rfb7r18 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
++ rfb7r19 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
++ rfb7r20 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x87);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0x27);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x38);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x38);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x80);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0xC1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x60);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
++
++ rt2800_bbp_write(rt2x00dev, 23, 0x0);
++ rt2800_bbp_write(rt2x00dev, 24, 0x0);
++
++ rt2800_bbp_dcoc_write(rt2x00dev, 5, 0x0);
++
++ bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
++ bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
++
++ rt2800_bbp_write(rt2x00dev, 241, 0x10);
++ rt2800_bbp_write(rt2x00dev, 242, 0x84);
++ rt2800_bbp_write(rt2x00dev, 244, 0x31);
++
++ bbpval = rt2800_bbp_dcoc_read(rt2x00dev, 3);
++ bbpval = bbpval & (~0x7);
++ rt2800_bbp_dcoc_write(rt2x00dev, 3, bbpval);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
++ udelay(1);
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
++ usleep_range(1, 200);
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003376);
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
++ udelay(1);
++ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
++ rt2800_bbp_write(rt2x00dev, 23, 0x06);
++ rt2800_bbp_write(rt2x00dev, 24, 0x06);
++ } else {
++ rt2800_bbp_write(rt2x00dev, 23, 0x02);
++ rt2800_bbp_write(rt2x00dev, 24, 0x02);
++ }
++
++ for (ch_idx = 0; ch_idx < 2; ch_idx = ch_idx + 1) {
++ if (ch_idx == 0) {
++ rfval = rfb0r1 & (~0x3);
++ rfval = rfb0r1 | 0x1;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
++ rfval = rfb0r2 & (~0x33);
++ rfval = rfb0r2 | 0x11;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
++ rfval = rfb0r42 & (~0x50);
++ rfval = rfb0r42 | 0x10;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
++ udelay(1);
++
++ bbpval = bbp1 & (~0x18);
++ bbpval = bbpval | 0x00;
++ rt2800_bbp_write(rt2x00dev, 1, bbpval);
++
++ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x00);
++ } else {
++ rfval = rfb0r1 & (~0x3);
++ rfval = rfb0r1 | 0x2;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
++ rfval = rfb0r2 & (~0x33);
++ rfval = rfb0r2 | 0x22;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
++ rfval = rfb0r42 & (~0x50);
++ rfval = rfb0r42 | 0x40;
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006);
++ udelay(1);
++
++ bbpval = bbp1 & (~0x18);
++ bbpval = bbpval | 0x08;
++ rt2800_bbp_write(rt2x00dev, 1, bbpval);
++
++ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x01);
++ }
++ usleep_range(500, 1500);
++
++ vga_idx = 0;
++ while (vga_idx < 11) {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rf_vga_table[vga_idx]);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rf_vga_table[vga_idx]);
++
++ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x93);
++
++ for (i = 0; i < 10000; i++) {
++ bbpval = rt2800_bbp_read(rt2x00dev, 159);
++ if ((bbpval & 0xff) == 0x93)
++ usleep_range(50, 100);
++ else
++ break;
++ }
++
++ if ((bbpval & 0xff) == 0x93) {
++ rt2x00_warn(rt2x00dev, "Fatal Error: Calibration doesn't finish");
++ goto restore_value;
++ }
++ for (i = 0; i < 5; i++) {
++ u32 bbptemp = 0;
++ u8 value = 0;
++ int result = 0;
++
++ rt2800_bbp_write(rt2x00dev, 158, 0x1e);
++ rt2800_bbp_write(rt2x00dev, 159, i);
++ rt2800_bbp_write(rt2x00dev, 158, 0x22);
++ value = rt2800_bbp_read(rt2x00dev, 159);
++ bbptemp = bbptemp + (value << 24);
++ rt2800_bbp_write(rt2x00dev, 158, 0x21);
++ value = rt2800_bbp_read(rt2x00dev, 159);
++ bbptemp = bbptemp + (value << 16);
++ rt2800_bbp_write(rt2x00dev, 158, 0x20);
++ value = rt2800_bbp_read(rt2x00dev, 159);
++ bbptemp = bbptemp + (value << 8);
++ rt2800_bbp_write(rt2x00dev, 158, 0x1f);
++ value = rt2800_bbp_read(rt2x00dev, 159);
++ bbptemp = bbptemp + value;
++
++ if (i < 2 && (bbptemp & 0x800000))
++ result = (bbptemp & 0xffffff) - 0x1000000;
++ else if (i == 4)
++ result = bbptemp;
++ else
++ result = bbptemp;
++
++ if (i == 0)
++ mi = result / 4096;
++ else if (i == 1)
++ mq = result / 4096;
++ else if (i == 2)
++ si = bbptemp / 4096;
++ else if (i == 3)
++ sq = bbptemp / 4096;
++ else
++ 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);
++
++ if (bbpval1 >= (100 * 100))
++ break;
++
++ if (bbpval1 <= 100)
++ vga_idx = vga_idx + 9;
++ else if (bbpval1 <= 158)
++ vga_idx = vga_idx + 8;
++ else if (bbpval1 <= 251)
++ vga_idx = vga_idx + 7;
++ else if (bbpval1 <= 398)
++ vga_idx = vga_idx + 6;
++ else if (bbpval1 <= 630)
++ vga_idx = vga_idx + 5;
++ else if (bbpval1 <= 1000)
++ vga_idx = vga_idx + 4;
++ else if (bbpval1 <= 1584)
++ vga_idx = vga_idx + 3;
++ else if (bbpval1 <= 2511)
++ vga_idx = vga_idx + 2;
++ else
++ 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));
++
++ 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);
++
++ 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");
++ }
++ } 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_warn(rt2x00dev, "RXIQ calibration FAIL");
++ }
++
++ if (ch_idx == 0) {
++ 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 {
++ rt2800_bbp_write(rt2x00dev, 158, 0x55);
++ rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
++ rt2800_bbp_write(rt2x00dev, 158, 0x53);
++ rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
++ }
++ }
++
++restore_value:
++ rt2800_bbp_write(rt2x00dev, 158, 0x3);
++ bbpval = rt2800_bbp_read(rt2x00dev, 159);
++ rt2800_bbp_write(rt2x00dev, 159, (bbpval | 0x07));
++
++ rt2800_bbp_write(rt2x00dev, 158, 0x00);
++ rt2800_bbp_write(rt2x00dev, 159, 0x00);
++ rt2800_bbp_write(rt2x00dev, 1, bbp1);
++ rt2800_bbp_write(rt2x00dev, 4, bbp4);
++ rt2800_bbp_write(rt2x00dev, 241, bbpr241);
++ rt2800_bbp_write(rt2x00dev, 242, bbpr242);
++
++ rt2800_bbp_write(rt2x00dev, 244, 0x00);
++ bbpval = rt2800_bbp_read(rt2x00dev, 21);
++ bbpval |= 0x1;
++ rt2800_bbp_write(rt2x00dev, 21, bbpval);
++ usleep_range(10, 200);
++ bbpval &= 0xfe;
++ rt2800_bbp_write(rt2x00dev, 21, bbpval);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfb0r1);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfb0r2);
++ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, rfb4r0);
++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 19, rfb4r19);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rfb5r3);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rfb5r4);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rfb5r17);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, rfb5r18);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, rfb5r19);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, rfb5r20);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, rfb6r0);
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 19, rfb6r19);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, rfb7r3);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, rfb7r4);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, rfb7r17);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, rfb7r18);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, rfb7r19);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, rfb7r20);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
++ udelay(1);
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
++ udelay(1);
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, orig_RF_CONTROL0);
++ udelay(1);
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, orig_RF_BYPASS0);
++ rt2800_register_write(rt2x00dev, RF_CONTROL1, orig_RF_CONTROL1);
++ rt2800_register_write(rt2x00dev, RF_BYPASS1, orig_RF_BYPASS1);
++ rt2800_register_write(rt2x00dev, RF_CONTROL3, orig_RF_CONTROL3);
++ rt2800_register_write(rt2x00dev, RF_BYPASS3, orig_RF_BYPASS3);
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
++}
++
+ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
+ bool set_bw, bool is_ht40)
+ {
+@@ -9278,6 +9652,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_rxiq_calibration(rt2x00dev);
+ }
+
+ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
--- /dev/null
+From patchwork Sat Sep 17 20:28:29 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979250
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:28:29 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 09/16] rt2x00: don't run Rt5592 IQ calibration on MT7620
+Message-ID:
+ <31a1c34ddbd296b82f38c18c9ae7339059215fdc.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+---
+v2: test for RT5592 instead of !RT6352
+
+ 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
+@@ -4398,7 +4398,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, RT5592))
++ rt2800_iq_calibrate(rt2x00dev, rf->channel);
+ }
+
+ if (rt2x00_rt(rt2x00dev, RT6352)) {
--- /dev/null
+From patchwork Sat Sep 17 20:28:43 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979251
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:28:43 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 10/16] rt2x00: add TX LOFT calibration for MT7620
+Message-ID:
+ <d9295a9138a1f552b648aacb84e1419d38f5c896.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+v2: use helper functions, make tables static const, remove useless
+ debug prints
+v3: don't export function not used anywhere else
+Reported-by: kernel test robot <lkp@intel.com>
+
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 902 ++++++++++++++++++
+ .../net/wireless/ralink/rt2x00/rt2800lib.h | 10 +
+ 2 files changed, 912 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -9041,6 +9041,907 @@ 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++) {
++ 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++) {
++ 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);
++}
++
++static 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;
++ 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 vga_gain[] = {14, 14};
++ 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;
++
++ static const u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c};
++ static const u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
++ 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F};
++ static const u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08};
++
++ 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);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX)))
++ rt2x00_warn(rt2x00dev, "RF TX busy in LOFT IQ calibration\n");
++
++ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ macvalue &= (~0x08);
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX)))
++ rt2x00_warn(rt2x00dev, "RF RX busy in LOFT IQ calibration\n");
++
++ 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);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX)))
++ rt2x00_warn(rt2x00dev, "RF TX busy in LOFT IQ calibration\n");
++
++ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
++ macvalue &= (~0x08);
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
++
++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX)))
++ rt2x00_warn(rt2x00dev, "RF RX busy in LOFT IQ calibration\n");
++
++ 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)
+ {
+@@ -9653,6 +10554,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 {
--- /dev/null
+From patchwork Sat Sep 17 20:28:58 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979252
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:28:58 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 11/16] rt2x00: move helper functions up in file
+Message-ID:
+ <c27baa8efd5c29e2bcb2432925d9cdc5c913a125.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ .../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
+@@ -198,6 +198,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)
+ {
+@@ -6947,26 +6967,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;
--- /dev/null
+From patchwork Sat Sep 17 20:29:13 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979253
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:29:13 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 12/16] rt2x00: fix HT20/HT40 bandwidth switch on MT7620
+Message-ID:
+ <1664d89ba149f7b0bcec18b2a2abaedf49654507.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -3855,6 +3855,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,
--- /dev/null
+From patchwork Sat Sep 17 20:29:26 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979254
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:29:26 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 13/16] rt2x00: set correct TX_SW_CFG1 MAC register for
+ MT7620
+Message-ID:
+ <4be38975ce600a34249e12d09a3cb758c6e71071.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -5966,7 +5966,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);
--- /dev/null
+From patchwork Sat Sep 17 20:29:40 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979255
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:29:40 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 14/16] rt2x00: set VGC gain for both chains of MT7620
+Message-ID:
+ <29e161397e5c9d9399da0fe87d44458aa2b90a78.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+Set bbp66 for all chains of the MT7620.
+
+Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -5743,7 +5743,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)) {
--- /dev/null
+From patchwork Sat Sep 17 20:29:55 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979256
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+Date: Sat, 17 Sep 2022 21:29:55 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 15/16] rt2x00: set SoC wmac clock register
+Message-ID:
+ <3e275d259f476f597dab91a9c395015ef3fe3284.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ .../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
+@@ -6229,6 +6229,27 @@ static int rt2800_init_registers(struct
+ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
+ rt2x00_set_field32(®, 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(®, US_CYC_CNT_CLOCK_CYCLE, rate);
++ rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
+ }
+
+ reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
--- /dev/null
+From patchwork Sat Sep 17 20:30:09 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12979257
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
+ aws-us-west-2-korg-lkml-1.web.codeaurora.org
+Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
+ by smtp.lore.kernel.org (Postfix) with ESMTP id E9118ECAAA1
+ for <linux-wireless@archiver.kernel.org>;
+ Sat, 17 Sep 2022 20:30:22 +0000 (UTC)
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S229639AbiIQUaV (ORCPT
+ <rfc822;linux-wireless@archiver.kernel.org>);
+ Sat, 17 Sep 2022 16:30:21 -0400
+Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53912 "EHLO
+ lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
+ with ESMTP id S229628AbiIQUaT (ORCPT
+ <rfc822;linux-wireless@vger.kernel.org>);
+ Sat, 17 Sep 2022 16:30:19 -0400
+Received: from fudo.makrotopia.org (fudo.makrotopia.org
+ [IPv6:2a07:2ec0:3002::71])
+ by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1AEA822B27
+ for <linux-wireless@vger.kernel.org>;
+ Sat, 17 Sep 2022 13:30:16 -0700 (PDT)
+Received: from local
+ by fudo.makrotopia.org with esmtpsa
+ (TLS1.3:TLS_AES_256_GCM_SHA384:256)
+ (Exim 4.96)
+ (envelope-from <daniel@makrotopia.org>)
+ id 1oZeS7-0003ra-0k;
+ Sat, 17 Sep 2022 22:30:15 +0200
+Date: Sat, 17 Sep 2022 21:30:09 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+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>
+Subject: [PATCH v3 16/16] rt2x00: correctly set BBP register 86 for MT7620
+Message-ID:
+ <257267247ee4fa7ebc6a5d0c4948b3f8119c0d77.1663445157.git.daniel@makrotopia.org>
+References: <cover.1663445157.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org>
+Precedence: bulk
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+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>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+---
+ 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
+@@ -4225,7 +4225,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) {
obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -37,6 +37,8 @@ struct rt2800_drv_data {
+@@ -47,6 +47,8 @@ struct rt2800_drv_data {
struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
};
struct rt2800_ops {
u32 (*register_read)(struct rt2x00_dev *rt2x00dev,
const unsigned int offset);
-@@ -135,6 +137,15 @@ static inline int rt2800_read_eeprom(str
+@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str
{
const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1401,6 +1401,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1419,6 +1419,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
/*
* Let the driver probe the device to detect the capabilities.
*/
-@@ -1541,6 +1545,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1559,6 +1563,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
* Free the driver data.
*/
kfree(rt2x00dev->drv_data);
#include "rt2x00.h"
#include "rt2800lib.h"
-@@ -9549,6 +9550,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -11131,6 +11132,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1340,7 +1340,7 @@ static inline void rt2x00lib_set_if_comb
+@@ -1358,7 +1358,7 @@ static inline void rt2x00lib_set_if_comb
*/
if_limit = &rt2x00dev->if_limits_ap;
if_limit->max = rt2x00dev->ops->max_ap_intf;
+++ /dev/null
-From: David Bauer <mail@david-bauer.net>
-Date: Mon, 16 Dec 2019 20:47:06 +0100
-Subject: [PATCH] rt2x00: add throughput LED trigger
-
-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>
----
- drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1125,6 +1125,19 @@ static void rt2x00lib_remove_hw(struct r
- kfree(rt2x00dev->spec.channels_info);
- }
-
-+static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
-+ { .throughput = 0 * 1024, .blink_time = 334 },
-+ { .throughput = 1 * 1024, .blink_time = 260 },
-+ { .throughput = 2 * 1024, .blink_time = 220 },
-+ { .throughput = 5 * 1024, .blink_time = 190 },
-+ { .throughput = 10 * 1024, .blink_time = 170 },
-+ { .throughput = 25 * 1024, .blink_time = 150 },
-+ { .throughput = 54 * 1024, .blink_time = 130 },
-+ { .throughput = 120 * 1024, .blink_time = 110 },
-+ { .throughput = 265 * 1024, .blink_time = 80 },
-+ { .throughput = 586 * 1024, .blink_time = 50 },
-+};
-+
- 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
-
- #undef RT2X00_TASKLET_INIT
-
-+ ieee80211_create_tpt_led_trigger(rt2x00dev->hw,
-+ IEEE80211_TPT_LEDTRIG_FL_RADIO, rt2x00_tpt_blink,
-+ ARRAY_SIZE(rt2x00_tpt_blink));
-+
- /*
- * Register HW.
- */
+++ /dev/null
-From 9782a7f7488443568fa4d6088b73c9aff7eb8510 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
-
-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.]
-
----
- drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 +
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++-
- 2 files changed, 70 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
-@@ -2739,6 +2739,7 @@ enum rt2800_eeprom_word {
- #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)
-
- /*
- * 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
- 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);
-+
-+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-+ reg |= 0x00000101;
-+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
-+
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
-+
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
-+ 0x36303636);
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
-+ 0x6C6C6B6C);
-+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
-+ 0x6C6C6B6C);
-+ }
-+ }
-+
- 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
- */
- eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
-
-- if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ if (rt2x00_rt(rt2x00dev, RT3352) ||
-+ rt2x00_rt(rt2x00dev, RT6352)) {
- 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
- &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);
-+ }
-+ }
-+
- return 0;
- }
-
+++ /dev/null
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
-Date: Mon, 8 Jan 2018 13:42:27 +0100
-Subject: [PATCH] rt2x00: add RF self TXDC calibration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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(+)
-
---- 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
- rt2800_led_open_drain_enable(rt2x00dev);
- }
-
-+static void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev)
-+{
-+ u8 rfb5r1_org, rfb7r1_org, rfvalue;
-+ 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);
-+ mac052c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
-+
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
-+
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0xC);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x3306);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL2, 0x3330);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0xfffff);
-+ rfb5r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
-+ rfb7r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, 0x4);
-+ for (i = 0; i < 100; i = i + 1) {
-+ udelay(50);
-+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
-+ 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);
-+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
-+ if((rfvalue & 0x04) != 0x4)
-+ break;
-+ }
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, rfb7r1_org);
-+
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, mac0518);
-+ 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
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
-
-+ rt2800_rf_self_txdc_cal(rt2x00dev);
- rt2800_bw_filter_calibration(rt2x00dev, true);
- rt2800_bw_filter_calibration(rt2x00dev, false);
- }
+++ /dev/null
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
-Date: Mon, 8 Jan 2018 13:42:58 +0100
-Subject: [PATCH] rt2x00: add r calibration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add r calibration code as found in mtk driver.
-
-Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
----
- .../net/wireless/ralink/rt2x00/rt2800lib.c | 150 ++++++++++++++++++
- 1 file changed, 150 insertions(+)
-
---- 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");
- }
-
-+static int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2)
-+{
-+ int calcode;
-+ calcode = ((d2 - d1) * 1000) / 43;
-+ if ((calcode%10) >= 5)
-+ calcode += 10;
-+ calcode = (calcode / 10);
-+
-+ return calcode;
-+}
-+
-+static void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev)
-+{
-+ u32 savemacsysctrl;
-+ u8 saverfb0r1, saverfb0r34, saverfb0r35;
-+ u8 saverfb5r4, saverfb5r17, saverfb5r18;
-+ u8 saverfb5r19, saverfb5r20;
-+ u8 savebbpr22, savebbpr47, savebbpr49;
-+ u8 bytevalue = 0;
-+ int rcalcode;
-+ u8 r_cal_code = 0;
-+ char d1 = 0, d2 = 0;
-+ u8 rfvalue;
-+ u32 MAC_RF_BYPASS0, MAC_RF_CONTROL0, MAC_PWR_PIN_CFG;
-+ u32 maccfg, macstatus;
-+ int i;
-+
-+ saverfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
-+ saverfb0r34 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 34);
-+ saverfb0r35 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
-+ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
-+ saverfb5r17 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
-+ saverfb5r18 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
-+ saverfb5r19 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
-+ saverfb5r20 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
-+
-+ savebbpr22 = rt2800_bbp_read(rt2x00dev, 22);
-+ savebbpr47 = rt2800_bbp_read(rt2x00dev, 47);
-+ savebbpr49 = rt2800_bbp_read(rt2x00dev, 49);
-+
-+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+ MAC_RF_BYPASS0 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
-+ MAC_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
-+ MAC_PWR_PIN_CFG = rt2800_register_read(rt2x00dev, PWR_PIN_CFG);
-+
-+ maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+ maccfg &= (~0x04);
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg);
-+
-+ for (i = 0; i < 10000; i++) {
-+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+ if (macstatus & 0x1)
-+ udelay(50);
-+ else
-+ break;
-+ }
-+
-+ if (i == 10000)
-+ rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n");
-+
-+ maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+ maccfg &= (~0x04);
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg);
-+
-+ for (i = 0; i < 10000; i++) {
-+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+ if (macstatus & 0x2)
-+ udelay(50);
-+ else
-+ break;
-+ }
-+
-+ if (i == 10000)
-+ rt2x00_warn(rt2x00dev, "Wait MAC Rx Status to MAX !!!\n");
-+
-+ rfvalue = (MAC_RF_BYPASS0 | 0x3004);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, rfvalue);
-+ rfvalue = (MAC_RF_CONTROL0 | (~0x3002));
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, rfvalue);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, 0x27);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, 0x80);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0x83);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x00);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x20);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x00);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 34, 0x13);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
-+
-+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x1);
-+
-+ rt2800_bbp_write(rt2x00dev, 47, 0x04);
-+ rt2800_bbp_write(rt2x00dev, 22, 0x80);
-+ udelay(100);
-+ bytevalue = rt2800_bbp_read(rt2x00dev, 49);
-+ if (bytevalue > 128)
-+ d1 = bytevalue - 256;
-+ else
-+ d1 = (char)bytevalue;
-+ rt2800_bbp_write(rt2x00dev, 22, 0x0);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x01);
-+
-+ rt2800_bbp_write(rt2x00dev, 22, 0x80);
-+ udelay(100);
-+ bytevalue = rt2800_bbp_read(rt2x00dev, 49);
-+ if (bytevalue > 128)
-+ d2 = bytevalue - 256;
-+ else
-+ d2 = (char)bytevalue;
-+ rt2800_bbp_write(rt2x00dev, 22, 0x0);
-+
-+ rcalcode = rt2800_calcrcalibrationcode(rt2x00dev, d1, d2);
-+ if (rcalcode < 0)
-+ r_cal_code = 256 + rcalcode;
-+ else
-+ r_cal_code = (u8)rcalcode;
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 7, r_cal_code);
-+
-+ rt2800_bbp_write(rt2x00dev, 22, 0x0);
-+
-+ bytevalue = rt2800_bbp_read(rt2x00dev, 21);
-+ bytevalue |= 0x1;
-+ rt2800_bbp_write(rt2x00dev, 21, bytevalue);
-+ bytevalue = rt2800_bbp_read(rt2x00dev, 21);
-+ bytevalue &= (~0x1);
-+ rt2800_bbp_write(rt2x00dev, 21, bytevalue);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, saverfb0r1);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 34, saverfb0r34);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, saverfb0r35);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, saverfb5r17);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, saverfb5r18);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, saverfb5r19);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, saverfb5r20);
-+
-+ rt2800_bbp_write(rt2x00dev, 22, savebbpr22);
-+ rt2800_bbp_write(rt2x00dev, 47, savebbpr47);
-+ rt2800_bbp_write(rt2x00dev, 49, savebbpr49);
-+
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, MAC_RF_CONTROL0);
-+
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
-+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
-+}
-+
- 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
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
-
-+ rt2800_r_calibration(rt2x00dev);
- rt2800_rf_self_txdc_cal(rt2x00dev);
- rt2800_bw_filter_calibration(rt2x00dev, true);
- rt2800_bw_filter_calibration(rt2x00dev, false);
+++ /dev/null
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
-Date: Mon, 8 Jan 2018 13:43:37 +0100
-Subject: [PATCH] rt2x00: add RXDCOC calibration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add RXDCOC calibration code from mtk driver.
-
-Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
----
- .../net/wireless/ralink/rt2x00/rt2800lib.c | 65 +++++++++++++++++++
- 1 file changed, 65 insertions(+)
-
---- 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
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
- }
-
-+static void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev)
-+{
-+ u8 bbpreg = 0;
-+ u32 macvalue = 0, macvalue1 = 0;
-+ u8 saverfb0r2, saverfb5r4, saverfb7r4, rfvalue;
-+ int i;
-+
-+ saverfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
-+ rfvalue = saverfb0r2;
-+ rfvalue |= 0x03;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfvalue);
-+
-+ rt2800_bbp_write(rt2x00dev, 158, 141);
-+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
-+ bbpreg |= 0x10;
-+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
-+
-+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x8);
-+
-+ for (i = 0; i < 10000; i++) {
-+ macvalue1 = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+ if (macvalue1 & 0x1)
-+ udelay(50);
-+ else
-+ break;
-+ }
-+
-+ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0);
-+ saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
-+ saverfb5r4 = saverfb5r4 & (~0x40);
-+ saverfb7r4 = saverfb7r4 & (~0x40);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x64);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4);
-+
-+ rt2800_bbp_write(rt2x00dev, 158, 141);
-+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
-+ bbpreg = bbpreg & (~0x40);
-+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
-+ bbpreg |= 0x48;
-+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
-+
-+ for (i = 0; i < 10000; i++) {
-+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
-+ if ((bbpreg & 0x40)==0)
-+ break;
-+ udelay(50);
-+ }
-+
-+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
-+ bbpreg = bbpreg & (~0x40);
-+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
-+
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
-+
-+ rt2800_bbp_write(rt2x00dev, 158, 141);
-+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
-+ bbpreg &= (~0x10);
-+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
-+}
-+
- 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
-
- rt2800_r_calibration(rt2x00dev);
- rt2800_rf_self_txdc_cal(rt2x00dev);
-+ rt2800_rxdcoc_calibration(rt2x00dev);
- rt2800_bw_filter_calibration(rt2x00dev, true);
- rt2800_bw_filter_calibration(rt2x00dev, false);
- }
+++ /dev/null
-From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
-Date: Mon, 8 Jan 2018 13:43:56 +0100
-Subject: [PATCH] rt2x00: add RXIQ calibration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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(+)
-
---- 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
- rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
- }
-
-+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)
-+ root = root_pre;
-+ bit = bit >> 1;
-+ }
-+
-+ return root;
-+}
-+
-+static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev) {
-+ u8 rfb0r1, rfb0r2, rfb0r42;
-+ u8 rfb4r0, rfb4r19;
-+ u8 rfb5r3, rfb5r4, rfb5r17, rfb5r18, rfb5r19, rfb5r20;
-+ u8 rfb6r0, rfb6r19;
-+ u8 rfb7r3, rfb7r4, rfb7r17, rfb7r18, rfb7r19, rfb7r20;
-+
-+ u8 bbp1, bbp4;
-+ u8 bbpr241, bbpr242;
-+ u32 i;
-+ u8 ch_idx;
-+ u8 bbpval;
-+ u8 rfval, vga_idx = 0;
-+ int mi = 0, mq = 0, si = 0, sq = 0, riq = 0;
-+ int sigma_i, sigma_q, r_iq, g_rx;
-+ int g_imb;
-+ int ph_rx;
-+ u32 savemacsysctrl = 0;
-+ u32 orig_RF_CONTROL0 = 0;
-+ u32 orig_RF_BYPASS0 = 0;
-+ u32 orig_RF_CONTROL1 = 0;
-+ u32 orig_RF_BYPASS1 = 0;
-+ u32 orig_RF_CONTROL3 = 0;
-+ u32 orig_RF_BYPASS3 = 0;
-+ u32 macstatus, bbpval1 = 0;
-+ u8 rf_vga_table[] = {0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
-+
-+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
-+ orig_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
-+ orig_RF_BYPASS0 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
-+ orig_RF_CONTROL1 = rt2800_register_read(rt2x00dev, RF_CONTROL1);
-+ orig_RF_BYPASS1 = rt2800_register_read(rt2x00dev, RF_BYPASS1);
-+ orig_RF_CONTROL3 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-+ orig_RF_BYPASS3 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-+
-+ bbp1 = rt2800_bbp_read(rt2x00dev, 1);
-+ bbp4 = rt2800_bbp_read(rt2x00dev, 4);
-+
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x0);
-+
-+ for (i = 0; i < 10000; i++) {
-+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
-+ if (macstatus & 0x3)
-+ udelay(50);
-+ else
-+ break;
-+ }
-+
-+ if (i == 10000)
-+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
-+
-+ bbpval = bbp4 & (~0x18);
-+ bbpval = bbp4 | 0x00;
-+ rt2800_bbp_write(rt2x00dev, 4, bbpval);
-+
-+ bbpval = rt2800_bbp_read(rt2x00dev, 21);
-+ bbpval = bbpval | 1;
-+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
-+ bbpval = bbpval & 0xfe;
-+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
-+
-+ rt2800_register_write(rt2x00dev, RF_CONTROL1, 0x00000202);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS1, 0x00000303);
-+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags))
-+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0101);
-+ else
-+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0000);
-+
-+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0xf1f1);
-+
-+ rfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
-+ rfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
-+ rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
-+ rfb4r0 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
-+ rfb4r19 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 19);
-+ rfb5r3 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
-+ rfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
-+ rfb5r17 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
-+ rfb5r18 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
-+ rfb5r19 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
-+ rfb5r20 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
-+
-+ rfb6r0 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
-+ rfb6r19 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 19);
-+ rfb7r3 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
-+ rfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
-+ rfb7r17 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
-+ rfb7r18 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
-+ rfb7r19 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
-+ rfb7r20 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
-+
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x87);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0x27);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x38);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x38);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x80);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0xC1);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x60);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
-+
-+ rt2800_bbp_write(rt2x00dev, 23, 0x0);
-+ rt2800_bbp_write(rt2x00dev, 24, 0x0);
-+
-+ rt2800_bbp_dcoc_write(rt2x00dev, 5, 0x0);
-+
-+ bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
-+ bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
-+
-+ rt2800_bbp_write(rt2x00dev, 241, 0x10);
-+ rt2800_bbp_write(rt2x00dev, 242, 0x84);
-+ rt2800_bbp_write(rt2x00dev, 244, 0x31);
-+
-+ bbpval = rt2800_bbp_dcoc_read(rt2x00dev, 3);
-+ bbpval = bbpval & (~0x7);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 3, bbpval);
-+
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
-+ udelay(1);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
-+ usleep_range(1, 200);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003376);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
-+ udelay(1);
-+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
-+ rt2800_bbp_write(rt2x00dev, 23, 0x06);
-+ rt2800_bbp_write(rt2x00dev, 24, 0x06);
-+ } else {
-+ rt2800_bbp_write(rt2x00dev, 23, 0x02);
-+ rt2800_bbp_write(rt2x00dev, 24, 0x02);
-+ }
-+
-+ for (ch_idx = 0; ch_idx < 2; ch_idx = ch_idx + 1) {
-+ if (ch_idx == 0) {
-+ rfval = rfb0r1 & (~0x3);
-+ rfval = rfb0r1 | 0x1;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
-+ rfval = rfb0r2 & (~0x33);
-+ rfval = rfb0r2 | 0x11;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
-+ rfval = rfb0r42 & (~0x50);
-+ rfval = rfb0r42 | 0x10;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
-+
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
-+ udelay(1);
-+
-+ bbpval = bbp1 & (~ 0x18);
-+ bbpval = bbpval | 0x00;
-+ rt2800_bbp_write(rt2x00dev, 1, bbpval);
-+
-+ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x00);
-+ } else {
-+ rfval = rfb0r1 & (~0x3);
-+ rfval = rfb0r1 | 0x2;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
-+ rfval = rfb0r2 & (~0x33);
-+ rfval = rfb0r2 | 0x22;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
-+ rfval = rfb0r42 & (~0x50);
-+ rfval = rfb0r42 | 0x40;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
-+
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006);
-+ udelay(1);
-+
-+ bbpval = bbp1 & (~ 0x18);
-+ bbpval = bbpval | 0x08;
-+ rt2800_bbp_write(rt2x00dev, 1, bbpval);
-+
-+ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x01);
-+ }
-+ udelay(500);
-+
-+ vga_idx = 0;
-+ while (vga_idx < 11) {
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rf_vga_table[vga_idx]);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rf_vga_table[vga_idx]);
-+
-+ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x93);
-+
-+ for (i = 0; i < 10000; i++) {
-+ bbpval = rt2800_bbp_read(rt2x00dev, 159);
-+ if ((bbpval & 0xff) == 0x93)
-+ udelay(50);
-+ else
-+ break;
-+ }
-+
-+ if ((bbpval & 0xff) == 0x93) {
-+ rt2x00_warn(rt2x00dev, "Fatal Error: Calibration doesn't finish");
-+ goto restore_value;
-+ }
-+
-+ for (i = 0; i < 5; i++) {
-+ u32 bbptemp = 0;
-+ u8 value = 0;
-+ int result = 0;
-+
-+ rt2800_bbp_write(rt2x00dev, 158, 0x1e);
-+ rt2800_bbp_write(rt2x00dev, 159, i);
-+ rt2800_bbp_write(rt2x00dev, 158, 0x22);
-+ value = rt2800_bbp_read(rt2x00dev, 159);
-+ bbptemp = bbptemp + (value << 24);
-+ rt2800_bbp_write(rt2x00dev, 158, 0x21);
-+ value = rt2800_bbp_read(rt2x00dev, 159);
-+ bbptemp = bbptemp + (value << 16);
-+ rt2800_bbp_write(rt2x00dev, 158, 0x20);
-+ value = rt2800_bbp_read(rt2x00dev, 159);
-+ bbptemp = bbptemp + (value << 8);
-+ rt2800_bbp_write(rt2x00dev, 158, 0x1f);
-+ value = rt2800_bbp_read(rt2x00dev, 159);
-+ bbptemp = bbptemp + value;
-+
-+ if ((i < 2) && (bbptemp & 0x800000))
-+ result = (bbptemp & 0xffffff) - 0x1000000;
-+ else if (i == 4)
-+ result = bbptemp;
-+ else
-+ result = bbptemp;
-+
-+ if (i == 0)
-+ mi = result/4096;
-+ else if (i == 1)
-+ mq = result/4096;
-+ else if (i == 2)
-+ si = bbptemp/4096;
-+ else if (i == 3)
-+ sq = bbptemp/4096;
-+ else
-+ 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);
-+
-+ if (bbpval1 >= (100*100))
-+ break;
-+
-+ if (bbpval1 <= 100)
-+ vga_idx = vga_idx + 9;
-+ else if (bbpval1 <= 158)
-+ vga_idx = vga_idx + 8;
-+ else if (bbpval1 <= 251)
-+ vga_idx = vga_idx + 7;
-+ else if (bbpval1 <= 398)
-+ vga_idx = vga_idx + 6;
-+ else if (bbpval1 <= 630)
-+ vga_idx = vga_idx + 5;
-+ else if (bbpval1 <= 1000)
-+ vga_idx = vga_idx + 4;
-+ else if (bbpval1 <= 1584)
-+ vga_idx = vga_idx + 3;
-+ else if (bbpval1 <= 2511)
-+ vga_idx = vga_idx + 2;
-+ else
-+ 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));
-+
-+ 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 ((g_imb > 12) || (g_imb < -12)) {
-+ g_imb = 0;
-+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
-+ }
-+ }
-+ 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_warn(rt2x00dev, "RXIQ calibration FAIL");
-+ }
-+
-+ if (ch_idx == 0) {
-+ 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 {
-+ rt2800_bbp_write(rt2x00dev, 158, 0x55);
-+ rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
-+ rt2800_bbp_write(rt2x00dev, 158, 0x53);
-+ rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
-+ }
-+ }
-+
-+restore_value:
-+ rt2800_bbp_write(rt2x00dev, 158, 0x3);
-+ bbpval = rt2800_bbp_read(rt2x00dev, 159);
-+ rt2800_bbp_write(rt2x00dev, 159, (bbpval | 0x07));
-+
-+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 1, bbp1);
-+ rt2800_bbp_write(rt2x00dev, 4, bbp4);
-+ rt2800_bbp_write(rt2x00dev, 241, bbpr241);
-+ rt2800_bbp_write(rt2x00dev, 242, bbpr242);
-+
-+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
-+ bbpval = rt2800_bbp_read(rt2x00dev, 21);
-+ bbpval |= 0x1;
-+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
-+ usleep_range(10, 200);
-+ bbpval &= 0xfe;
-+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfb0r1);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfb0r2);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, rfb4r0);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 19, rfb4r19);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rfb5r3);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rfb5r4);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rfb5r17);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, rfb5r18);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, rfb5r19);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, rfb5r20);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, rfb6r0);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 19, rfb6r19);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, rfb7r3);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, rfb7r4);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, rfb7r17);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, rfb7r18);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, rfb7r19);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, rfb7r20);
-+
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
-+ udelay(1);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
-+ udelay(1);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL0, orig_RF_CONTROL0);
-+ udelay(1);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS0, orig_RF_BYPASS0);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL1, orig_RF_CONTROL1);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS1, orig_RF_BYPASS1);
-+ rt2800_register_write(rt2x00dev, RF_CONTROL3, orig_RF_CONTROL3);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS3, orig_RF_BYPASS3);
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
-+}
-+
- 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
- rt2800_rxdcoc_calibration(rt2x00dev);
- rt2800_bw_filter_calibration(rt2x00dev, true);
- rt2800_bw_filter_calibration(rt2x00dev, false);
-+ rt2800_rxiq_calibration(rt2x00dev);
- }
-
- static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+++ /dev/null
-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 {
+++ /dev/null
---- 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 = {
+++ /dev/null
---- 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(®, 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);
--- /dev/null
+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,
+@@ -4469,6 +4487,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);
+@@ -10583,6 +10624,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);
+@@ -10590,6 +10632,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:
--- /dev/null
+--- 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 = {
--- /dev/null
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -1044,6 +1044,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
+@@ -3778,14 +3778,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,
+@@ -3819,18 +3821,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)) {
+@@ -3929,25 +3936,29 @@ static void rt2800_config_alc(struct rt2
+ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY)))
+ rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\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);
+@@ -6011,18 +6022,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(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0);
+ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
+@@ -7127,14 +7153,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);
+@@ -10408,31 +10436,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);
+@@ -10498,63 +10531,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);
+@@ -10617,12 +10658,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);
};
};
+ pa_gpio_pins: pa_gpio {
+ pa {
+ groups = "pa";
+ function = "gpio";
+ };
+ };
+
sdhci_pins: sdhci {
sdhci {
groups = "nd_sd";
&wmac {
ralink,mtd-eeprom = <&factory 0x0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
&factory {
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
ralink,mtd-eeprom = <&factory 0x0>;
nvmem-cells = <&macaddr_factory_28>;
&wmac {
ralink,mtd-eeprom = <&factory 0x0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
&factory {
&wmac {
ralink,mtd-eeprom = <&factory 0x0>;
- pinctrl-names = "default";
+
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>, <&wled_pins>;
+ pinctrl-1 = <&pa_gpio_pins>, <&wled_pins>;
};
&pcie {
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
};
&wmac {
- ralink,mtd-eeprom = <&factory 0x0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
+
+ ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
nvmem-cells = <&macaddr_rom_f100>;
nvmem-cell-names = "mac-address";
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
nvmem-cells = <&macaddr_rom_f100>;
nvmem-cell-names = "mac-address";
};
&wmac {
- pinctrl-names = "default";
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&wmac {
ralink,mtd-eeprom = <&factory 0x0>;
- pinctrl-names = "default";
+
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
&pcie {
&wmac {
ralink,mtd-eeprom = <&factory 0x0>;
+
+ pinctrl-names = "default", "pa_gpio";
+ pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
&sdhci {
&wmac {
ralink,mtd-eeprom = <&factory 0x0>;
- pinctrl-names = "default";
+
+ pinctrl-names = "default", "pa_gpio";
pinctrl-0 = <&pa_pins>;
+ pinctrl-1 = <&pa_gpio_pins>;
};
&pcie {