mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 08:21:14 +00:00
6bcd1c2501
Some local patches have been sent to upstream and they are slightly different from the upstream version. So it's better to replace them to avoid conflicts with the new mac80211 backport driver. The different parts have been merged into patch 996. This commit also includes some additional fixes: * Fix watchdog function. * Improve MT7620 register initialization. * Introduce DMA busy watchdog for rt2800. P.S. Sometimes rt2800 series chips may fall into a DMA busy state. The tx queues become very slow and the client cannot connect to the AP. Usually, We can see a lot of hostapd warnings at this point: 'hostapd: IEEE 802.11: did not acknowledge authentication response' The DMA busy watchdog can help the driver automatically recover from this abnormal state. By the way, setting higer 'cell_density' and disabling 'disassoc_low_ack' can significantly reduce the probability of the DMA busy. Signed-off-by: Shiji Yang <yangshiji66@qq.com>
242 lines
8.8 KiB
Diff
242 lines
8.8 KiB
Diff
From cca74bed37af1c8217bcd8282d9b384efdbf73bd Mon Sep 17 00:00:00 2001
|
|
From: Shiji Yang <yangshiji66@outlook.com>
|
|
Date: Thu, 19 Oct 2023 19:58:58 +0800
|
|
Subject: wifi: rt2x00: rework MT7620 PA/LNA RF calibration
|
|
|
|
1. Move MT7620 PA/LNA calibration code to dedicated functions.
|
|
2. For external PA/LNA devices, restore RF and BBP registers before
|
|
R-Calibration.
|
|
3. Do Rx DCOC calibration again before RXIQ calibration.
|
|
4. Add some missing LNA related registers' initialization.
|
|
|
|
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
|
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
|
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
|
Link: https://lore.kernel.org/r/TYAP286MB0315979F92DC563019B8F238BCD4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
|
|
---
|
|
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 176 +++++++++++++++++--------
|
|
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 6 +
|
|
2 files changed, 130 insertions(+), 52 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
|
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
|
@@ -4468,41 +4468,6 @@ static void rt2800_config_channel(struct
|
|
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
|
|
|
|
usleep_range(1000, 1500);
|
|
-
|
|
- 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);
|
|
@@ -5612,16 +5577,6 @@ void rt2800_vco_calibration(struct rt2x0
|
|
}
|
|
}
|
|
rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
|
|
-
|
|
- if (rt2x00_rt(rt2x00dev, RT6352)) {
|
|
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
|
|
- 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);
|
|
- }
|
|
- }
|
|
}
|
|
EXPORT_SYMBOL_GPL(rt2800_vco_calibration);
|
|
|
|
@@ -10348,6 +10303,128 @@ do_cal:
|
|
rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0);
|
|
}
|
|
|
|
+static void rt2800_restore_rf_bbp_rt6352(struct rt2x00_dev *rt2x00dev)
|
|
+{
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
|
|
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0);
|
|
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0);
|
|
+ }
|
|
+
|
|
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
|
|
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
|
|
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
|
|
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02);
|
|
+ }
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
|
|
+ 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_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, 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 (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
|
|
+ rt2800_bbp_write(rt2x00dev, 75, 0x60);
|
|
+ rt2800_bbp_write(rt2x00dev, 76, 0x44);
|
|
+ rt2800_bbp_write(rt2x00dev, 79, 0x1c);
|
|
+ rt2800_bbp_write(rt2x00dev, 80, 0x0c);
|
|
+ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
|
|
+ }
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
|
|
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x3630363a);
|
|
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6c6c666c);
|
|
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6c6c666c);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void rt2800_calibration_rt6352(struct rt2x00_dev *rt2x00dev)
|
|
+{
|
|
+ u32 reg;
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev) ||
|
|
+ rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
|
+ rt2800_restore_rf_bbp_rt6352(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);
|
|
+ rt2800_loft_iq_calibration(rt2x00dev);
|
|
+
|
|
+ /* missing DPD calibration for internal PA devices */
|
|
+
|
|
+ rt2800_rxdcoc_calibration(rt2x00dev);
|
|
+ rt2800_rxiq_calibration(rt2x00dev);
|
|
+
|
|
+ if (!rt2x00_has_cap_external_pa(rt2x00dev) &&
|
|
+ !rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
|
+ return;
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(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);
|
|
+ }
|
|
+
|
|
+ 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);
|
|
+ }
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
|
|
+ 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);
|
|
+ }
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev))
|
|
+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
|
|
+
|
|
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
|
|
+ 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);
|
|
+ }
|
|
+
|
|
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
|
|
+ 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);
|
|
+ }
|
|
+}
|
|
+
|
|
static void rt2800_init_rfcsr_6352(struct rt2x00_dev *rt2x00dev)
|
|
{
|
|
/* Initialize RF central register to default value */
|
|
@@ -10612,13 +10689,8 @@ 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_rxdcoc_calibration(rt2x00dev);
|
|
- rt2800_bw_filter_calibration(rt2x00dev, true);
|
|
- rt2800_bw_filter_calibration(rt2x00dev, false);
|
|
- rt2800_loft_iq_calibration(rt2x00dev);
|
|
- rt2800_rxiq_calibration(rt2x00dev);
|
|
+ /* Do calibration and init PA/LNA */
|
|
+ rt2800_calibration_rt6352(rt2x00dev);
|
|
}
|
|
|
|
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
|
|
@@ -1263,6 +1263,12 @@ rt2x00_has_cap_external_lna_bg(struct rt
|
|
}
|
|
|
|
static inline bool
|
|
+rt2x00_has_cap_external_pa(struct rt2x00_dev *rt2x00dev)
|
|
+{
|
|
+ return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_PA_TX0);
|
|
+}
|
|
+
|
|
+static inline bool
|
|
rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev)
|
|
{
|
|
return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_DOUBLE_ANTENNA);
|