2022-09-17 20:27:44

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 00/16] rt2x00: OpenWrt patches improving MT7620 (and more)

Over the years we have been accumulating a number of patches improving
support for the IEEE 802.11bgn 2T2R wireless interface built into the
MediaTek MT7620 MIPS SoCs. Many of them have not been in shape for
being submitted to Linux and changes were needed to make checkpatch.pl
all happy (it is now). Now they look as good as it gets, given that
most code deals with undocumented registers and was adapted from the
vendor driver.

Patch 01/16 also has been previously submitted and then (imho wrongly)
rejected, so I've included it in this series with an updated commit
message.

Patch 02/16 also has been previously submitted but never received any
feedback. I've also included it here again because having a more
informative LED trigger is definitely an improvement.

Alltogether rt2x00 now performs almost as good as the vendor driver,
see benchmark of HT20 client below:

Accepted connection from 192.168.5.133, port 37382
[ 5] local 192.168.5.175 port 5201 connected to 192.168.5.133 port 37384
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 9.57 MBytes 80.3 Mbits/sec
[ 5] 1.00-2.00 sec 9.68 MBytes 81.2 Mbits/sec
[ 5] 2.00-3.00 sec 9.98 MBytes 83.7 Mbits/sec
[ 5] 3.00-4.00 sec 9.72 MBytes 81.6 Mbits/sec
[ 5] 4.00-5.00 sec 9.49 MBytes 79.6 Mbits/sec
[ 5] 5.00-6.00 sec 9.88 MBytes 82.9 Mbits/sec
[ 5] 6.00-7.00 sec 9.76 MBytes 81.8 Mbits/sec
[ 5] 7.00-8.00 sec 9.96 MBytes 83.6 Mbits/sec
[ 5] 8.00-9.00 sec 9.76 MBytes 81.9 Mbits/sec
[ 5] 9.00-10.00 sec 9.86 MBytes 82.7 Mbits/sec
[ 5] 10.00-10.03 sec 243 KBytes 78.4 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.03 sec 97.9 MBytes 81.9 Mbits/sec receiver

Accepted connection from 192.168.5.133, port 49588
[ 5] local 192.168.5.175 port 5201 connected to 192.168.5.133 port 49598
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 12.7 MBytes 106 Mbits/sec 0 557 KBytes
[ 5] 1.00-2.00 sec 11.1 MBytes 93.0 Mbits/sec 0 1020 KBytes
[ 5] 2.00-3.00 sec 11.2 MBytes 94.4 Mbits/sec 0 1.57 MBytes
[ 5] 3.00-4.00 sec 11.2 MBytes 94.4 Mbits/sec 0 1.58 MBytes
[ 5] 4.00-5.00 sec 10.0 MBytes 83.9 Mbits/sec 0 1.58 MBytes
[ 5] 5.00-6.00 sec 11.2 MBytes 94.4 Mbits/sec 0 1.58 MBytes
[ 5] 6.00-7.00 sec 11.2 MBytes 94.4 Mbits/sec 0 1.58 MBytes
[ 5] 7.00-8.00 sec 10.0 MBytes 83.9 Mbits/sec 0 1.58 MBytes
[ 5] 8.00-9.00 sec 12.5 MBytes 105 Mbits/sec 0 1.58 MBytes
[ 5] 9.00-10.00 sec 10.0 MBytes 83.9 Mbits/sec 0 1.58 MBytes
[ 5] 10.00-10.03 sec 1.25 MBytes 381 Mbits/sec 0 1.58 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.03 sec 112 MBytes 94.1 Mbits/sec 0 sender

v2: comments from Stanislaw Gruszka have been addressed.
v3: don't export function only used inside rt2800lib.c
Reported-by: kernel test robot <[email protected]>

Daniel Golle (9):
rt2x00: add support for external PA on MT7620
rt2x00: move up and reuse busy wait functions
rt2x00: don't run Rt5592 IQ calibration on MT7620
rt2x00: move helper functions up in file
rt2x00: fix HT20/HT40 bandwidth switch on MT7620
rt2x00: set correct TX_SW_CFG1 MAC register for MT7620
rt2x00: set VGC gain for both chains of MT7620
rt2x00: set SoC wmac clock register
rt2x00: correctly set BBP register 86 for MT7620

David Bauer (1):
rt2x00: add throughput LED trigger

Tomislav Požega (6):
rt2x00: define RF5592 in init_eeprom routine
rt2x00: add RF self TXDC calibration for MT7620
rt2x00: add r calibration for MT7620
rt2x00: add RXDCOC calibration for MT7620
rt2x00: add RXIQ calibration for MT7620
rt2x00: add TX LOFT calibration for MT7620

drivers/net/wireless/ralink/rt2x00/rt2800.h | 3 +
.../net/wireless/ralink/rt2x00/rt2800lib.c | 1753 ++++++++++++++++-
.../net/wireless/ralink/rt2x00/rt2800lib.h | 10 +
.../net/wireless/ralink/rt2x00/rt2x00dev.c | 18 +
4 files changed, 1706 insertions(+), 78 deletions(-)

--
2.37.3


2022-09-17 20:27:56

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 01/16] rt2x00: define RF5592 in init_eeprom routine

From: Tomislav Požega <[email protected]>

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 <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 18102fbe36d6cc..cc9c5554fdc9ca 100644
--- 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 rt2x00_dev *rt2x00dev)
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);

--
2.37.3

2022-09-17 20:28:01

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 03/16] rt2x00: add support for external PA on MT7620

Implement support for external PA connected to MT7620A.

Signed-off-by: Tomislav Požega <[email protected]>
[[email protected]: use chanreg and dccal helpers.]
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 +
.../net/wireless/ralink/rt2x00/rt2800lib.c | 52 ++++++++++++++++++-
2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index d758e887445783..431502021dc2fe 100644
--- 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
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index cc9c5554fdc9ca..b34453bd87174f 100644
--- 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 rt2x00_dev *rt2x00dev,
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 rt2x00_dev *rt2x00dev)
*/
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 rt2x00_dev *rt2x00dev)
&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;
}

--
2.37.3

2022-09-17 20:28:17

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 04/16] rt2x00: move up and reuse busy wait functions

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 <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 99 +++++++++----------
1 file changed, 46 insertions(+), 53 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index b34453bd87174f..cf5463cb7b642b 100644
--- 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 *rt2x00dev, struct rt2x00lib_erp *erp,
}
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 rt2x00_dev *rt2x00dev,
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 rt2x00_dev *rt2x00dev,
/* 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 rt2x00_dev *rt2x00dev)
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_dev *rt2x00dev)
/*
* 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;

/*
--
2.37.3

2022-09-17 20:28:40

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 05/16] rt2x00: add RF self TXDC calibration for MT7620

From: Tomislav Požega <[email protected]>

Add TX self calibration based on mtk driver.

Signed-off-by: Tomislav Požega <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
v2: use ++i instead of i = i + 1 in loops

.../net/wireless/ralink/rt2x00/rt2800lib.c | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index cf5463cb7b642b..ed2c6105899b8d 100644
--- 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(struct rt2x00_dev *rt2x00dev)
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(struct rt2x00_dev *rt2x00dev)
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);
}
--
2.37.3

2022-09-17 20:28:56

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 06/16] rt2x00: add r calibration for MT7620

From: Tomislav Požega <[email protected]>

Add r calibration code as found in mtk driver.

Signed-off-by: Tomislav Požega <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
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(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index 431502021dc2fe..de2ee5ffc34e7b 100644
--- 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:
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index ed2c6105899b8d..df5038a59046fe 100644
--- 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(struct rt2x00_dev *rt2x00dev)
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(struct rt2x00_dev *rt2x00dev)
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);
--
2.37.3

2022-09-17 20:29:15

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 07/16] rt2x00: add RXDCOC calibration for MT7620

From: Tomislav Požega <[email protected]>

Add RXDCOC calibration code from mtk driver.

Signed-off-by: Tomislav Požega <[email protected]>
[fixed typo reported by Serge Vasilugin <[email protected]>]
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index df5038a59046fe..a785e6616c748a 100644
--- 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 rt2x00_dev *rt2x00dev)
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(struct rt2x00_dev *rt2x00dev)

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

2022-09-17 20:29:17

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 09/16] rt2x00: don't run Rt5592 IQ calibration on MT7620

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 <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
v2: test for RT5592 instead of !RT6352

drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 2dc197b508ad32..4b912b362562c9 100644
--- 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 rt2x00_dev *rt2x00dev,
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)) {
--
2.37.3

2022-09-17 20:29:31

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 10/16] rt2x00: add TX LOFT calibration for MT7620

From: Tomislav Požega <[email protected]>

Add TX LOFT calibration from mtk driver.

Signed-off-by: Tomislav Požega <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
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 <[email protected]>

.../net/wireless/ralink/rt2x00/rt2800lib.c | 902 ++++++++++++++++++
.../net/wireless/ralink/rt2x00/rt2800lib.h | 10 +
2 files changed, 912 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 4b912b362562c9..afcb4e18bf763e 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -9041,6 +9041,907 @@ static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev)
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(struct rt2x00_dev *rt2x00dev)
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);
}

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
index e1761f467b9465..3cbef77b4bd306 100644
--- 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 {
--
2.37.3

2022-09-17 20:29:40

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 11/16] rt2x00: move helper functions up in file

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 <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 40 +++++++++----------
1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index afcb4e18bf763e..73e962b3618b39 100644
--- 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(struct rt2x00_dev *rt2x00dev,
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 rt2x00_dev *rt2x00dev)
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;
--
2.37.3

2022-09-17 20:29:56

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 12/16] rt2x00: fix HT20/HT40 bandwidth switch on MT7620

Add missing configuration of the channel bandwidth filter to the
channel setup function for MT7620.

Reported-by: Serge Vasilugin <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 73e962b3618b39..b20c5aae9aaedc 100644
--- 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(struct rt2x00_dev *rt2x00dev,
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,
--
2.37.3

2022-09-17 20:29:57

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 13/16] rt2x00: set correct TX_SW_CFG1 MAC register for MT7620

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 <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index b20c5aae9aaedc..48c695bf69a590 100644
--- 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 rt2x00_dev *rt2x00dev)
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);
--
2.37.3

2022-09-17 20:30:49

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 02/16] rt2x00: add throughput LED trigger

From: David Bauer <[email protected]>

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 <[email protected]>
Signed-off-by: David Bauer <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index e95c101c271113..3a035afcf7f99c 100644
--- 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 rt2x00_dev *rt2x00dev)
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 rt2x00_dev *rt2x00dev)

#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.
*/
--
2.37.3

2022-09-17 20:31:03

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 08/16] rt2x00: add RXIQ calibration for MT7620

From: Tomislav Požega <[email protected]>

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 <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
v2: use rt2800_wait_bbp_rf_ready(), fix indentation

.../net/wireless/ralink/rt2x00/rt2800lib.c | 375 ++++++++++++++++++
1 file changed, 375 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index a785e6616c748a..2dc197b508ad32 100644
--- 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(struct rt2x00_dev *rt2x00dev)
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(struct rt2x00_dev *rt2x00dev)
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)
--
2.37.3

2022-09-17 20:31:08

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 14/16] rt2x00: set VGC gain for both chains of MT7620

Set bbp66 for all chains of the MT7620.

Reported-by: Serge Vasilugin <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 48c695bf69a590..f25ab41f580564 100644
--- 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 rt2x00_dev *rt2x00dev,
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)) {
--
2.37.3

2022-09-17 20:31:21

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 15/16] rt2x00: set SoC wmac clock register

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 <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index f25ab41f580564..ecd475e7c0218f 100644
--- 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 rt2x00_dev *rt2x00dev)
reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 125);
rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
+ } else if (rt2x00_is_soc(rt2x00dev)) {
+ struct clk *clk = clk_get_sys("bus", NULL);
+ int rate;
+
+ if (IS_ERR(clk)) {
+ clk = clk_get_sys("cpu", NULL);
+
+ if (IS_ERR(clk)) {
+ rate = 125;
+ } else {
+ rate = clk_get_rate(clk) / 3000000;
+ clk_put(clk);
+ }
+ } else {
+ rate = clk_get_rate(clk) / 1000000;
+ clk_put(clk);
+ }
+
+ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
+ rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, rate);
+ rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
}

reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
--
2.37.3

2022-09-17 20:33:19

by Daniel Golle

[permalink] [raw]
Subject: [PATCH v3 16/16] rt2x00: correctly set BBP register 86 for MT7620

Instead of 0 set the correct value for BBP register 86 for MT7620.

Reported-by: Serge Vasilugin <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Acked-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index ecd475e7c0218f..cbbb1a4849cff0 100644
--- 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 rt2x00_dev *rt2x00dev,
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) {
--
2.37.3

2022-09-22 05:08:35

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v3 02/16] rt2x00: add throughput LED trigger

Daniel Golle <[email protected]> wrote:

> From: David Bauer <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: David Bauer <[email protected]>
> Acked-by: Stanislaw Gruszka <[email protected]>

This is missing Daniel's s-o-b.

--
https://patchwork.kernel.org/project/linux-wireless/patch/73f5ba4134e621462a26186449400cf0c1ac1730.1663445157.git.daniel@makrotopia.org/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2022-09-22 05:11:44

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v3 02/16] rt2x00: add throughput LED trigger

Kalle Valo <[email protected]> writes:

> Daniel Golle <[email protected]> wrote:
>
>> From: David Bauer <[email protected]>
>>
>> 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 <[email protected]>
>> Signed-off-by: David Bauer <[email protected]>
>> Acked-by: Stanislaw Gruszka <[email protected]>
>
> This is missing Daniel's s-o-b.

Otherwise the patchset looked good to me. Daniel, if you can give your
s-o-b as a reply to this mail I can then add it during commit.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2022-09-22 20:19:01

by Daniel Golle

[permalink] [raw]
Subject: Re: [PATCH v3 02/16] rt2x00: add throughput LED trigger

On Thu, Sep 22, 2022 at 08:00:13AM +0300, Kalle Valo wrote:
> Kalle Valo <[email protected]> writes:
>
> > Daniel Golle <[email protected]> wrote:
> >
> >> From: David Bauer <[email protected]>
> >>
> >> 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 <[email protected]>
> >> Signed-off-by: David Bauer <[email protected]>
> >> Acked-by: Stanislaw Gruszka <[email protected]>
> >
> > This is missing Daniel's s-o-b.
>
> Otherwise the patchset looked good to me. Daniel, if you can give your
> s-o-b as a reply to this mail I can then add it during commit.

Signed-off-by: Daniel Golle <[email protected]>

Thank you!

>
> --
> https://patchwork.kernel.org/project/linux-wireless/list/
>
> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2022-09-24 12:38:45

by Kalle Valo

[permalink] [raw]
Subject: Re: [v3,01/16] wifi: rt2x00: define RF5592 in init_eeprom routine

Daniel Golle <[email protected]> wrote:

> From: Tomislav Požega <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Daniel Golle <[email protected]>
> Acked-by: Stanislaw Gruszka <[email protected]>

16 patches applied to wireless-next.git, thanks.

3fdff7e08117 wifi: rt2x00: define RF5592 in init_eeprom routine
47c40fd2440e wifi: rt2x00: add throughput LED trigger
d7320a377168 wifi: rt2x00: add support for external PA on MT7620
685bcf2f9a13 wifi: rt2x00: move up and reuse busy wait functions
26d76c370f69 wifi: rt2x00: add RF self TXDC calibration for MT7620
bdcac97f143e wifi: rt2x00: add r calibration for MT7620
c8ce49ff0b83 wifi: rt2x00: add RXDCOC calibration for MT7620
ab7b2295732f wifi: rt2x00: add RXIQ calibration for MT7620
d3aad83d05ae wifi: rt2x00: don't run Rt5592 IQ calibration on MT7620
dab902fe1d29 wifi: rt2x00: add TX LOFT calibration for MT7620
79b4c9455e0b wifi: rt2x00: move helper functions up in file
d5ed439cf00a wifi: rt2x00: fix HT20/HT40 bandwidth switch on MT7620
eeb50acf1576 wifi: rt2x00: set correct TX_SW_CFG1 MAC register for MT7620
0e09768c0857 wifi: rt2x00: set VGC gain for both chains of MT7620
cbde6ed406a5 wifi: rt2x00: set SoC wmac clock register
c9aada64fe64 wifi: rt2x00: correctly set BBP register 86 for MT7620

--
https://patchwork.kernel.org/project/linux-wireless/patch/d7eccb2c7b8ec4cd360fa2007796abffc35abb0d.1663445157.git.daniel@makrotopia.org/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches