From 6bcd1c2501b521fa6da7e4f7c55c3fe4b373a16d Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Wed, 25 Oct 2023 20:09:23 +0800 Subject: [PATCH] mac80211: sync some rt2x00 patches with wireless-next 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 --- .../patches/ath/400-ath_move_debug_code.patch | 2 +- ...rect-MAC_SYS_CTRL-register-RX-mask-i.patch | 28 ++ ...mit-MT7620-TX-power-based-on-eeprom.patch} | 47 +- ...fi-rt2x00-fix-MT7620-low-RSSI-issue.patch} | 12 +- ...-rt2x00-fix-rt2800-watchdog-function.patch | 78 ++++ ...prove-MT7620-register-initialization.patch | 124 ++++++ ...ework-MT7620-channel-config-function.patch | 146 +++++++ ...-rework-MT7620-PA-LNA-RF-calibration.patch | 241 ++++++++++ ...oduce-DMA-busy-check-watchdog-for-rt.patch | 177 ++++++++ ...ble-RTS-threshold-for-rt2800-by-defa.patch | 43 ++ ...art-beacon-queue-when-hardware-reset.patch | 67 +++ ...-support-for-loading-EEPROM-from-MTD.patch | 3 +- ...port-loading-eeprom-from-NVMEM-cells.patch | 3 +- ...isabling_bands_through_platform_data.patch | 2 +- ...07-rt2x00-add_platform_data_mac_addr.patch | 2 +- ...00-allow_disabling_bands_through_dts.patch | 2 +- ...0-rt2x00-change-led-polarity-from-OF.patch | 2 +- .../611-rt2x00-add-AP+STA-support.patch | 2 +- ...t-support-for-external-LNA-on-MT7620.patch | 74 +--- ...-differentiate-based-on-SoC-CHIP_VER.patch | 108 +++-- ...-rework-MT7620-PA-LNA-RF-calibration.patch | 413 ------------------ 21 files changed, 1035 insertions(+), 541 deletions(-) create mode 100644 package/kernel/mac80211/patches/rt2x00/000-v6.6-wifi-rt2x00-correct-MAC_SYS_CTRL-register-RX-mask-i.patch rename package/kernel/mac80211/patches/rt2x00/{997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch => 001-v6.6-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom.patch} (73%) rename package/kernel/mac80211/patches/rt2x00/{999-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch => 002-v6.7-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch} (76%) create mode 100644 package/kernel/mac80211/patches/rt2x00/003-v6.7-wifi-rt2x00-fix-rt2800-watchdog-function.patch create mode 100644 package/kernel/mac80211/patches/rt2x00/004-1-v6.7-wifi-rt2x00-improve-MT7620-register-initialization.patch create mode 100644 package/kernel/mac80211/patches/rt2x00/004-2-v6.7-wifi-rt2x00-rework-MT7620-channel-config-function.patch create mode 100644 package/kernel/mac80211/patches/rt2x00/004-3-v6.7-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch create mode 100644 package/kernel/mac80211/patches/rt2x00/005-1-v6.8-wifi-rt2x00-introduce-DMA-busy-check-watchdog-for-rt.patch create mode 100644 package/kernel/mac80211/patches/rt2x00/005-2-v6.8-wifi-rt2x00-disable-RTS-threshold-for-rt2800-by-defa.patch create mode 100644 package/kernel/mac80211/patches/rt2x00/005-3-v6.8-wifi-rt2x00-restart-beacon-queue-when-hardware-reset.patch delete mode 100644 package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch diff --git a/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch index 4c6b175ebe21..23b7340e25c4 100644 --- a/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch +++ b/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch @@ -14,7 +14,7 @@ CFLAGS_trace.o := -I$(src) --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h -@@ -319,14 +319,7 @@ void _ath_dbg(struct ath_common *common, +@@ -321,14 +321,7 @@ void _ath_dbg(struct ath_common *common, #endif /* CPTCFG_ATH_DEBUG */ /** Returns string describing opmode, or NULL if unknown mode. */ diff --git a/package/kernel/mac80211/patches/rt2x00/000-v6.6-wifi-rt2x00-correct-MAC_SYS_CTRL-register-RX-mask-i.patch b/package/kernel/mac80211/patches/rt2x00/000-v6.6-wifi-rt2x00-correct-MAC_SYS_CTRL-register-RX-mask-i.patch new file mode 100644 index 000000000000..c84b5a140840 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/000-v6.6-wifi-rt2x00-correct-MAC_SYS_CTRL-register-RX-mask-i.patch @@ -0,0 +1,28 @@ +From 186f2432741f6d28d86ff723ac7830446affddfc Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sat, 5 Aug 2023 17:17:28 +0800 +Subject: wifi: rt2x00: correct MAC_SYS_CTRL register RX mask in R-Calibration + +For MAC_SYS_CTRL register, Bit[2] controls MAC_TX_EN and Bit[3] +controls MAC_RX_EN (Bit index starts from 0). Therefore, 0x08 is +the correct mask for RX. + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB03150B571B67B896A504AC34BC0EA@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -8561,7 +8561,7 @@ static void rt2800_r_calibration(struct + rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n"); + + maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); +- maccfg &= (~0x04); ++ maccfg &= (~0x08); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg); + + if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX))) diff --git a/package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch b/package/kernel/mac80211/patches/rt2x00/001-v6.6-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom.patch similarity index 73% rename from package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch rename to package/kernel/mac80211/patches/rt2x00/001-v6.6-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom.patch index fd1b3d8bf3b6..aa843d421987 100644 --- a/package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch +++ b/package/kernel/mac80211/patches/rt2x00/001-v6.6-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom.patch @@ -1,7 +1,7 @@ +From 821b5192c955144bd2f0aeea6cd153e1aedd16e1 Mon Sep 17 00:00:00 2001 From: Shiji Yang -Date: Sat, 22 Jul 2023 21:56:30 +0800 -Subject: [PATCH] wifi: rt2x00: limit MT7620 TX power based on eeprom - calibration +Date: Fri, 11 Aug 2023 14:34:54 +0800 +Subject: wifi: rt2x00: limit MT7620 TX power based on eeprom calibration In the vendor driver, the current channel power is queried from EEPROM_TXPOWER_BG1 and EEPROM_TXPOWER_BG2. And then the mixed value @@ -18,29 +18,36 @@ Based on these eeprom values, this patch adds basic TX power control for the MT7620 and limits its maximum TX power. This can avoid the link speed decrease caused by chip overheating. rt2800_config_alc() function has also been renamed to rt2800_config_alc_rt6352() because -it's only used by RT6352(MT7620). +it's only used by RT6352 (MT7620). Notice: It's still need some work to sync the max channel power to the user -interface. This part is missing from the rt2x00 driver structure. If +interface. This part is missing from the rt2x00 driver framework. If we set the power exceed the calibration value, it won't take effect. Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB03159090ED14044215E59FD6BC10A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM --- - .../net/wireless/ralink/rt2x00/rt2800lib.c | 49 +++++++++++++------ - 1 file changed, 34 insertions(+), 15 deletions(-) + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 57 ++++++++++++++++++-------- + 1 file changed, 40 insertions(+), 17 deletions(-) --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3891,28 +3891,47 @@ static void rt2800_config_channel_rf7620 +@@ -3865,28 +3865,51 @@ static void rt2800_config_channel_rf7620 } } -static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev, -+static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev, - struct ieee80211_channel *chan, - int power_level) { +- struct ieee80211_channel *chan, +- int power_level) { - u16 eeprom, target_power, max_power; ++static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_channel *chan, ++ int power_level) ++{ ++ int cur_channel = rt2x00dev->rf_channel; + u16 eeprom, chan_power, rate_power, target_power; + u16 tx_power[2]; + s8 *power_group[2]; @@ -57,27 +64,29 @@ Signed-off-by: Shiji Yang - max_power = chan->max_power * 2; - if (max_power > 0x2f) - max_power = 0x2f; -+ /* get per channel power, 2 channels in total, unit is 0.5dBm */ ++ if (WARN_ON(cur_channel < 1 || cur_channel > 14)) ++ return; ++ ++ /* get per chain power, 2 chains in total, unit is 0.5dBm */ + power_level = (power_level - 3) * 2; -+ /* -+ * We can't get the accurate TX power. Based on some tests, the real ++ ++ /* We can't get the accurate TX power. Based on some tests, the real + * TX power is approximately equal to channel_power + (max)rate_power. + * Usually max rate_power is the gain of the OFDM 6M rate. The antenna + * gain and externel PA gain are not included as we are unable to + * obtain these values. + */ + rate_power = rt2800_eeprom_read_from_array(rt2x00dev, -+ EEPROM_TXPOWER_BYRATE, 1) & 0x3f; ++ EEPROM_TXPOWER_BYRATE, 1); ++ rate_power &= 0x3f; + power_level -= rate_power; + if (power_level < 1) + power_level = 1; -+ if (power_level > chan->max_power * 2) -+ power_level = chan->max_power * 2; + + power_group[0] = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); + power_group[1] = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); + for (cnt = 0; cnt < 2; cnt++) { -+ chan_power = power_group[cnt][rt2x00dev->rf_channel - 1]; ++ chan_power = power_group[cnt][cur_channel - 1]; + if (chan_power >= 0x20 || chan_power == 0) + chan_power = 0x10; + tx_power[cnt] = power_level < chan_power ? power_level : chan_power; @@ -95,7 +104,7 @@ Signed-off-by: Shiji Yang eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) { -@@ -5321,7 +5340,7 @@ static void rt2800_config_txpower_rt6352 +@@ -5268,7 +5291,7 @@ static void rt2800_config_txpower_rt6352 rt2x00_set_field32(&pwreg, TX_PWR_CFG_9B_STBC_MCS7, t); rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, pwreg); diff --git a/package/kernel/mac80211/patches/rt2x00/999-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch b/package/kernel/mac80211/patches/rt2x00/002-v6.7-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch similarity index 76% rename from package/kernel/mac80211/patches/rt2x00/999-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch rename to package/kernel/mac80211/patches/rt2x00/002-v6.7-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch index 8f7343d14e30..ffb66559d173 100644 --- a/package/kernel/mac80211/patches/rt2x00/999-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch +++ b/package/kernel/mac80211/patches/rt2x00/002-v6.7-wifi-rt2x00-fix-MT7620-low-RSSI-issue.patch @@ -1,6 +1,7 @@ +From 2ecfe6f07e8e6257cad3d3290c5aec2102120041 Mon Sep 17 00:00:00 2001 From: Shiji Yang -Date: Sat, 23 Sep 2023 07:51:39 +0800 -Subject: [PATCH] wifi: rt2x00: fix MT7620 low RSSI issue +Date: Sat, 23 Sep 2023 09:01:01 +0800 +Subject: wifi: rt2x00: fix MT7620 low RSSI issue On Mediatek vendor driver[1], MT7620 (RT6352) uses different RSSI base value '-2' compared to the other RT2x00 chips. This patch @@ -10,13 +11,16 @@ reports on MT7620. [1] Found on MT76x2E_MT7620_LinuxAP_V3.0.4.0_P3 ConvertToRssi(). Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB031571CDB146C414A908A66DBCFEA@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -875,6 +875,7 @@ static int rt2800_agc_to_rssi(struct rt2 +@@ -856,6 +856,7 @@ static int rt2800_agc_to_rssi(struct rt2 s8 rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); s8 rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); s8 rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2); @@ -24,7 +28,7 @@ Signed-off-by: Shiji Yang u16 eeprom; u8 offset0; u8 offset1; -@@ -899,9 +900,9 @@ static int rt2800_agc_to_rssi(struct rt2 +@@ -880,9 +881,9 @@ static int rt2800_agc_to_rssi(struct rt2 * If the value in the descriptor is 0, it is considered invalid * and the default (extremely low) rssi value is assumed */ diff --git a/package/kernel/mac80211/patches/rt2x00/003-v6.7-wifi-rt2x00-fix-rt2800-watchdog-function.patch b/package/kernel/mac80211/patches/rt2x00/003-v6.7-wifi-rt2x00-fix-rt2800-watchdog-function.patch new file mode 100644 index 000000000000..f253dacf2b22 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/003-v6.7-wifi-rt2x00-fix-rt2800-watchdog-function.patch @@ -0,0 +1,78 @@ +From 69708fbb2c698f262e03360d064c7066e0679953 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sat, 14 Oct 2023 14:55:01 +0800 +Subject: wifi: rt2x00: fix rt2800 watchdog function + +The watchdog function is broken on rt2800 series SoCs. This patch +fixes the incorrect watchdog logic to make it work again. + +1. Update current wdt queue index if it's not equal to the previous + index. Watchdog compares the current and previous queue index to + judge if the queue hung. +2. Make sure hung_{rx,tx} 'true' status won't be override by the + normal queue. Any queue hangs should trigger a reset action. +3. Clear the watchdog counter of all queues before resetting the + hardware. This change may help to avoid the reset loop. +4. Change hang check function return type to bool as we only need + to return two status, yes or no. + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB0315BC1D83D31154924F0D39BCD1A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1237,13 +1237,14 @@ void rt2800_txdone_nostatus(struct rt2x0 + } + EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus); + +-static int rt2800_check_hung(struct data_queue *queue) ++static bool rt2800_check_hung(struct data_queue *queue) + { + unsigned int cur_idx = rt2800_drv_get_dma_done(queue); + +- if (queue->wd_idx != cur_idx) ++ if (queue->wd_idx != cur_idx) { ++ queue->wd_idx = cur_idx; + queue->wd_count = 0; +- else ++ } else + queue->wd_count++; + + return queue->wd_count > 16; +@@ -1280,7 +1281,7 @@ void rt2800_watchdog(struct rt2x00_dev * + case QID_MGMT: + if (rt2x00queue_empty(queue)) + continue; +- hung_tx = rt2800_check_hung(queue); ++ hung_tx = hung_tx || rt2800_check_hung(queue); + break; + case QID_RX: + /* For station mode we should reactive at least +@@ -1289,7 +1290,7 @@ void rt2800_watchdog(struct rt2x00_dev * + */ + if (rt2x00dev->intf_sta_count == 0) + continue; +- hung_rx = rt2800_check_hung(queue); ++ hung_rx = hung_rx || rt2800_check_hung(queue); + break; + default: + break; +@@ -1302,8 +1303,12 @@ void rt2800_watchdog(struct rt2x00_dev * + if (hung_rx) + rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n"); + +- if (hung_tx || hung_rx) ++ if (hung_tx || hung_rx) { ++ queue_for_each(rt2x00dev, queue) ++ queue->wd_count = 0; ++ + ieee80211_restart_hw(rt2x00dev->hw); ++ } + } + EXPORT_SYMBOL_GPL(rt2800_watchdog); + diff --git a/package/kernel/mac80211/patches/rt2x00/004-1-v6.7-wifi-rt2x00-improve-MT7620-register-initialization.patch b/package/kernel/mac80211/patches/rt2x00/004-1-v6.7-wifi-rt2x00-improve-MT7620-register-initialization.patch new file mode 100644 index 000000000000..9f4dbb8346e1 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/004-1-v6.7-wifi-rt2x00-improve-MT7620-register-initialization.patch @@ -0,0 +1,124 @@ +From 1ffe76d5ae78553948d67a978acd9945c2f0a175 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Thu, 19 Oct 2023 19:58:56 +0800 +Subject: wifi: rt2x00: improve MT7620 register initialization + +1. Do not hard reset the BBP. We can use soft reset instead. This + change has some help to the calibration failure issue. +2. Enable falling back to legacy rate from the HT/RTS rate by + setting the HT_FBK_TO_LEGACY register. +3. Implement MCS rate specific maximum PSDU size. It can improve + the transmission quality under the low RSSI condition. +4. Set BBP_84 register value to 0x19. This is used for extension + channel overlapping IOT. + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB031553CCD4B7A3B89C85935DBCD4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 18 ++++++++++++++++++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 24 ++++++++++++++++++++++++ + drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 3 +++ + 3 files changed, 45 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -871,6 +871,18 @@ + #define LED_CFG_LED_POLAR FIELD32(0x40000000) + + /* ++ * AMPDU_MAX_LEN_20M1S: Per MCS max A-MPDU length, 20 MHz, MCS 0-7 ++ * AMPDU_MAX_LEN_20M2S: Per MCS max A-MPDU length, 20 MHz, MCS 8-15 ++ * AMPDU_MAX_LEN_40M1S: Per MCS max A-MPDU length, 40 MHz, MCS 0-7 ++ * AMPDU_MAX_LEN_40M2S: Per MCS max A-MPDU length, 40 MHz, MCS 8-15 ++ * Maximum A-MPDU length = 2^(AMPDU_MAX - 5) kilobytes ++ */ ++#define AMPDU_MAX_LEN_20M1S 0x1030 ++#define AMPDU_MAX_LEN_20M2S 0x1034 ++#define AMPDU_MAX_LEN_40M1S 0x1038 ++#define AMPDU_MAX_LEN_40M2S 0x103C ++ ++/* + * AMPDU_BA_WINSIZE: Force BlockAck window size + * FORCE_WINSIZE_ENABLE: + * 0: Disable forcing of BlockAck window size +@@ -1545,6 +1557,12 @@ + */ + #define EXP_ACK_TIME 0x1380 + ++/* ++ * HT_FBK_TO_LEGACY: Enable/Disable HT/RTS fallback to OFDM/CCK rate ++ * Not available for legacy SoCs ++ */ ++#define HT_FBK_TO_LEGACY 0x1384 ++ + /* TX_PWR_CFG_5 */ + #define TX_PWR_CFG_5 0x1384 + #define TX_PWR_CFG_5_MCS16_CH0 FIELD32(0x0000000f) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5851,6 +5851,7 @@ static int rt2800_init_registers(struct + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u32 reg; + u16 eeprom; ++ u8 bbp; + unsigned int i; + int ret; + +@@ -5860,6 +5861,19 @@ static int rt2800_init_registers(struct + if (ret) + return ret; + ++ if (rt2x00_rt(rt2x00dev, RT6352)) { ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x01); ++ ++ bbp = rt2800_bbp_read(rt2x00dev, 21); ++ bbp |= 0x01; ++ rt2800_bbp_write(rt2x00dev, 21, bbp); ++ bbp = rt2800_bbp_read(rt2x00dev, 21); ++ bbp &= (~0x01); ++ rt2800_bbp_write(rt2x00dev, 21, bbp); ++ ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00); ++ } ++ + rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f); + rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); + +@@ -6013,6 +6027,14 @@ static int rt2800_init_registers(struct + reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); + rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); + rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); ++ ++ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_20M1S, 0x77754433); ++ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_20M2S, 0x77765543); ++ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_40M1S, 0x77765544); ++ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_40M2S, 0x77765544); ++ ++ rt2800_register_write(rt2x00dev, HT_FBK_TO_LEGACY, 0x1010); ++ + } else { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); +@@ -7231,6 +7253,8 @@ static void rt2800_init_bbp_6352(struct + rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64); + + rt2800_bbp4_mac_if_ctrl(rt2x00dev); ++ ++ rt2800_bbp_write(rt2x00dev, 84, 0x19); + } + + static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -760,6 +760,9 @@ int rt2800mmio_init_registers(struct rt2 + + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + ++ if (rt2x00_rt(rt2x00dev, RT6352)) ++ return 0; ++ + reg = 0; + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); diff --git a/package/kernel/mac80211/patches/rt2x00/004-2-v6.7-wifi-rt2x00-rework-MT7620-channel-config-function.patch b/package/kernel/mac80211/patches/rt2x00/004-2-v6.7-wifi-rt2x00-rework-MT7620-channel-config-function.patch new file mode 100644 index 000000000000..1aec73d76221 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/004-2-v6.7-wifi-rt2x00-rework-MT7620-channel-config-function.patch @@ -0,0 +1,146 @@ +From a28533c6be1711584bf3ec978309d5c590029821 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Thu, 19 Oct 2023 19:58:57 +0800 +Subject: wifi: rt2x00: rework MT7620 channel config function + +1. Move the channel configuration code from rt2800_vco_calibration() + to the rt2800_config_channel(). +2. Use MT7620 SoC specific AGC initial LNA value instead of the + RT5592's value. +3. BBP{195,196} pairing write has been replaced with + rt2800_bbp_glrt_write() to reduce redundant code. + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB0315622A4340BFFA530B1B86BCD4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 91 ++++++++++---------------- + 1 file changed, 35 insertions(+), 56 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3861,14 +3861,6 @@ static void rt2800_config_channel_rf7620 + rfcsr |= tx_agc_fc; + rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); + } +- +- if (conf_is_ht40(conf)) { +- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10); +- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f); +- } else { +- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a); +- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40); +- } + } + + static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev, +@@ -4437,32 +4429,46 @@ static void rt2800_config_channel(struct + usleep_range(1000, 1500); + } + +- if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { +- reg = 0x10; +- if (!conf_is_ht40(conf)) { +- if (rt2x00_rt(rt2x00dev, RT6352) && +- rt2x00_has_cap_external_lna_bg(rt2x00dev)) { +- reg |= 0x5; +- } else { +- reg |= 0xa; +- } +- } +- rt2800_bbp_write(rt2x00dev, 195, 141); +- rt2800_bbp_write(rt2x00dev, 196, reg); ++ if (rt2x00_rt(rt2x00dev, RT5592)) { ++ bbp = conf_is_ht40(conf) ? 0x10 : 0x1a; ++ rt2800_bbp_glrt_write(rt2x00dev, 141, bbp); + +- /* AGC init. +- * Despite the vendor driver using different values here for +- * RT6352 chip, we use 0x1c for now. This may have to be changed +- * once TSSI got implemented. +- */ +- reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; +- rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); ++ bbp = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain; ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); + +- if (rt2x00_rt(rt2x00dev, RT5592)) +- rt2800_iq_calibrate(rt2x00dev, rf->channel); ++ rt2800_iq_calibrate(rt2x00dev, rf->channel); + } + + if (rt2x00_rt(rt2x00dev, RT6352)) { ++ /* BBP for GLRT BW */ ++ bbp = conf_is_ht40(conf) ? ++ 0x10 : rt2x00_has_cap_external_lna_bg(rt2x00dev) ? ++ 0x15 : 0x1a; ++ rt2800_bbp_glrt_write(rt2x00dev, 141, bbp); ++ ++ bbp = conf_is_ht40(conf) ? 0x2f : 0x40; ++ rt2800_bbp_glrt_write(rt2x00dev, 157, bbp); ++ ++ if (rt2x00dev->default_ant.rx_chain_num == 1) { ++ rt2800_bbp_write(rt2x00dev, 91, 0x07); ++ rt2800_bbp_write(rt2x00dev, 95, 0x1a); ++ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xa0); ++ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x12); ++ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x10); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 91, 0x06); ++ rt2800_bbp_write(rt2x00dev, 95, 0x9a); ++ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xe0); ++ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30); ++ } ++ ++ /* AGC init */ ++ bbp = rf->channel <= 14 ? 0x04 + 2 * rt2x00dev->lna_gain : 0; ++ 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); +@@ -5608,26 +5614,6 @@ void rt2800_vco_calibration(struct rt2x0 + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + + if (rt2x00_rt(rt2x00dev, RT6352)) { +- if (rt2x00dev->default_ant.rx_chain_num == 1) { +- rt2800_bbp_write(rt2x00dev, 91, 0x07); +- rt2800_bbp_write(rt2x00dev, 95, 0x1A); +- rt2800_bbp_write(rt2x00dev, 195, 128); +- rt2800_bbp_write(rt2x00dev, 196, 0xA0); +- rt2800_bbp_write(rt2x00dev, 195, 170); +- rt2800_bbp_write(rt2x00dev, 196, 0x12); +- rt2800_bbp_write(rt2x00dev, 195, 171); +- rt2800_bbp_write(rt2x00dev, 196, 0x10); +- } else { +- rt2800_bbp_write(rt2x00dev, 91, 0x06); +- rt2800_bbp_write(rt2x00dev, 95, 0x9A); +- rt2800_bbp_write(rt2x00dev, 195, 128); +- rt2800_bbp_write(rt2x00dev, 196, 0xE0); +- rt2800_bbp_write(rt2x00dev, 195, 170); +- rt2800_bbp_write(rt2x00dev, 196, 0x30); +- rt2800_bbp_write(rt2x00dev, 195, 171); +- rt2800_bbp_write(rt2x00dev, 196, 0x30); +- } +- + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 75, 0x68); + rt2800_bbp_write(rt2x00dev, 76, 0x4C); +@@ -5635,13 +5621,6 @@ void rt2800_vco_calibration(struct rt2x0 + rt2800_bbp_write(rt2x00dev, 80, 0x0C); + rt2800_bbp_write(rt2x00dev, 82, 0xB6); + } +- +- /* On 11A, We should delay and wait RF/BBP to be stable +- * and the appropriate time should be 1000 micro seconds +- * 2005/06/05 - On 11G, we also need this delay time. +- * Otherwise it's difficult to pass the WHQL. +- */ +- usleep_range(1000, 1500); + } + } + EXPORT_SYMBOL_GPL(rt2800_vco_calibration); diff --git a/package/kernel/mac80211/patches/rt2x00/004-3-v6.7-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch b/package/kernel/mac80211/patches/rt2x00/004-3-v6.7-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch new file mode 100644 index 000000000000..64cd599c02b3 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/004-3-v6.7-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch @@ -0,0 +1,241 @@ +From cca74bed37af1c8217bcd8282d9b384efdbf73bd Mon Sep 17 00:00:00 2001 +From: Shiji Yang +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 +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +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); diff --git a/package/kernel/mac80211/patches/rt2x00/005-1-v6.8-wifi-rt2x00-introduce-DMA-busy-check-watchdog-for-rt.patch b/package/kernel/mac80211/patches/rt2x00/005-1-v6.8-wifi-rt2x00-introduce-DMA-busy-check-watchdog-for-rt.patch new file mode 100644 index 000000000000..c1c322573305 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/005-1-v6.8-wifi-rt2x00-introduce-DMA-busy-check-watchdog-for-rt.patch @@ -0,0 +1,177 @@ +From b1275cdd7456ef811747dfb4f3c46310ddd300cd Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sat, 4 Nov 2023 16:57:58 +0800 +Subject: wifi: rt2x00: introduce DMA busy check watchdog for rt2800 + +When I tried to fix the watchdog of rt2800, I found that sometimes +the watchdog can not reset the hung device. This is because the +queue is not completely stuck, it just becomes very slow. The MTK +vendor driver for the new chip MT7603/MT7612 has a DMA busy watchdog +to detect device hangs by checking DMA busy status. This watchdog +implementation is something similar to it. To reduce unnecessary +reset, we can check the INT_SOURCE_CSR register together as I found +that when the radio hung, the RX/TX coherent interrupt will always +stuck at triggered state. + +The 'watchdog' module parameter has been extended to control all +watchdogs(0=disabled, 1=hang watchdog, 2=DMA watchdog, 3=both). This +new watchdog function is a slight schedule and it won't affect the +transmission speed. So we can turn on it by default. Due to the +INT_SOURCE_CSR register is invalid on rt2800 USB NICs, the DMA busy +watchdog will be automatically disabled for them. + +Tested on MT7620 and RT5350. + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB0315D7462CE08A119A99DE34BCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 4 ++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 77 ++++++++++++++++++++++---- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 3 + + 3 files changed, 73 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -3194,4 +3194,8 @@ enum rt2800_eeprom_word { + */ + #define BCN_TBTT_OFFSET 64 + ++/* Watchdog type mask */ ++#define RT2800_WATCHDOG_HANG BIT(0) ++#define RT2800_WATCHDOG_DMA_BUSY BIT(1) ++ + #endif /* RT2800_H */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -30,9 +30,10 @@ + #include "rt2800lib.h" + #include "rt2800.h" + +-static bool modparam_watchdog; +-module_param_named(watchdog, modparam_watchdog, bool, S_IRUGO); +-MODULE_PARM_DESC(watchdog, "Enable watchdog to detect tx/rx hangs and reset hardware if detected"); ++static unsigned int modparam_watchdog = RT2800_WATCHDOG_DMA_BUSY; ++module_param_named(watchdog, modparam_watchdog, uint, 0444); ++MODULE_PARM_DESC(watchdog, "Enable watchdog to recover tx/rx hangs.\n" ++ "\t\t(0=disabled, 1=hang watchdog, 2=DMA watchdog(default), 3=both)"); + + /* + * Register access. +@@ -1261,15 +1262,12 @@ static void rt2800_update_survey(struct + chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); + } + +-void rt2800_watchdog(struct rt2x00_dev *rt2x00dev) ++static bool rt2800_watchdog_hung(struct rt2x00_dev *rt2x00dev) + { + struct data_queue *queue; + bool hung_tx = false; + bool hung_rx = false; + +- if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) +- return; +- + rt2800_update_survey(rt2x00dev); + + queue_for_each(rt2x00dev, queue) { +@@ -1297,18 +1295,72 @@ void rt2800_watchdog(struct rt2x00_dev * + } + } + ++ if (!hung_tx && !hung_rx) ++ return false; ++ + if (hung_tx) + rt2x00_warn(rt2x00dev, "Watchdog TX hung detected\n"); + + if (hung_rx) + rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n"); + +- if (hung_tx || hung_rx) { +- queue_for_each(rt2x00dev, queue) +- queue->wd_count = 0; ++ queue_for_each(rt2x00dev, queue) ++ queue->wd_count = 0; ++ ++ return true; ++} ++ ++static bool rt2800_watchdog_dma_busy(struct rt2x00_dev *rt2x00dev) ++{ ++ bool busy_rx, busy_tx; ++ u32 reg_cfg = rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG); ++ u32 reg_int = rt2800_register_read(rt2x00dev, INT_SOURCE_CSR); ++ ++ if (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_RX_DMA_BUSY) && ++ rt2x00_get_field32(reg_int, INT_SOURCE_CSR_RX_COHERENT)) ++ rt2x00dev->rxdma_busy++; ++ else ++ rt2x00dev->rxdma_busy = 0; + ++ if (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_TX_DMA_BUSY) && ++ rt2x00_get_field32(reg_int, INT_SOURCE_CSR_TX_COHERENT)) ++ rt2x00dev->txdma_busy++; ++ else ++ rt2x00dev->txdma_busy = 0; ++ ++ busy_rx = rt2x00dev->rxdma_busy > 30 ? true : false; ++ busy_tx = rt2x00dev->txdma_busy > 30 ? true : false; ++ ++ if (!busy_rx && !busy_tx) ++ return false; ++ ++ if (busy_rx) ++ rt2x00_warn(rt2x00dev, "Watchdog RX DMA busy detected\n"); ++ ++ if (busy_tx) ++ rt2x00_warn(rt2x00dev, "Watchdog TX DMA busy detected\n"); ++ ++ rt2x00dev->rxdma_busy = 0; ++ rt2x00dev->txdma_busy = 0; ++ ++ return true; ++} ++ ++void rt2800_watchdog(struct rt2x00_dev *rt2x00dev) ++{ ++ bool reset = false; ++ ++ if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) ++ return; ++ ++ if (modparam_watchdog & RT2800_WATCHDOG_DMA_BUSY) ++ reset = rt2800_watchdog_dma_busy(rt2x00dev); ++ ++ if (modparam_watchdog & RT2800_WATCHDOG_HANG) ++ reset = rt2800_watchdog_hung(rt2x00dev) || reset; ++ ++ if (reset) + ieee80211_restart_hw(rt2x00dev->hw); +- } + } + EXPORT_SYMBOL_GPL(rt2800_watchdog); + +@@ -12016,6 +12068,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r + __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags); + } + ++ /* USB NICs don't support DMA watchdog as INT_SOURCE_CSR is invalid */ ++ if (rt2x00_is_usb(rt2x00dev)) ++ modparam_watchdog &= ~RT2800_WATCHDOG_DMA_BUSY; + if (modparam_watchdog) { + __set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags); + rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100); +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -926,6 +926,9 @@ struct rt2x00_dev { + */ + u16 beacon_int; + ++ /* Rx/Tx DMA busy watchdog counter */ ++ u16 rxdma_busy, txdma_busy; ++ + /** + * Timestamp of last received beacon + */ diff --git a/package/kernel/mac80211/patches/rt2x00/005-2-v6.8-wifi-rt2x00-disable-RTS-threshold-for-rt2800-by-defa.patch b/package/kernel/mac80211/patches/rt2x00/005-2-v6.8-wifi-rt2x00-disable-RTS-threshold-for-rt2800-by-defa.patch new file mode 100644 index 000000000000..b3e95da5a60d --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/005-2-v6.8-wifi-rt2x00-disable-RTS-threshold-for-rt2800-by-defa.patch @@ -0,0 +1,43 @@ +From 570beb6285fd355904b22625da20809f477096c5 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sat, 4 Nov 2023 16:57:59 +0800 +Subject: wifi: rt2x00: disable RTS threshold for rt2800 by default + +rt2800 has a lot of registers to control the RTS enable/disable +status for different rates. And the driver control them via +rt2800_set_rts_threshold(). When RTS was disabled in user +interface, this function won't be called at all. This means that +the RTS is still 'on' for CCK and OFDM rates. So we'd better to +disable them by default because it should be like this. The RTS +for HT20 and HT40 is already default off so we don't need to +touch them. If we toggle the RTS status, these register bits +will be enable/disable again by rt2800_set_rts_threshold(). + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB03155DDB953155B7A2DE849ABCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -6100,7 +6100,7 @@ static int rt2800_init_registers(struct + rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0); + rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1); + rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0); +- rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, 1); ++ rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, 0); + rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg); + + reg = rt2800_register_read(rt2x00dev, OFDM_PROT_CFG); +@@ -6113,7 +6113,7 @@ static int rt2800_init_registers(struct + rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0); + rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1); + rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0); +- rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, 1); ++ rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, 0); + rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); + + reg = rt2800_register_read(rt2x00dev, MM20_PROT_CFG); diff --git a/package/kernel/mac80211/patches/rt2x00/005-3-v6.8-wifi-rt2x00-restart-beacon-queue-when-hardware-reset.patch b/package/kernel/mac80211/patches/rt2x00/005-3-v6.8-wifi-rt2x00-restart-beacon-queue-when-hardware-reset.patch new file mode 100644 index 000000000000..1fa7b8b0fb99 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/005-3-v6.8-wifi-rt2x00-restart-beacon-queue-when-hardware-reset.patch @@ -0,0 +1,67 @@ +From a11d965a218f0cd95b13fe44d0bcd8a20ce134a8 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sat, 4 Nov 2023 16:58:00 +0800 +Subject: wifi: rt2x00: restart beacon queue when hardware reset + +When a hardware reset is triggered, all registers are reset, so all +queues are forced to stop in hardware interface. However, mac80211 +will not automatically stop the queue. If we don't manually stop the +beacon queue, the queue will be deadlocked and unable to start again. +This patch fixes the issue where Apple devices cannot connect to the +AP after calling ieee80211_restart_hw(). + +Signed-off-by: Shiji Yang +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYAP286MB031530EB6D98DCE4DF20766CBCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 3 +++ + drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 11 +++++++++++ + 2 files changed, 14 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -101,6 +101,7 @@ void rt2x00lib_disable_radio(struct rt2x + rt2x00link_stop_tuner(rt2x00dev); + rt2x00queue_stop_queues(rt2x00dev); + rt2x00queue_flush_queues(rt2x00dev, true); ++ rt2x00queue_stop_queue(rt2x00dev->bcn); + + /* + * Disable radio. +@@ -1286,6 +1287,7 @@ int rt2x00lib_start(struct rt2x00_dev *r + rt2x00dev->intf_ap_count = 0; + rt2x00dev->intf_sta_count = 0; + rt2x00dev->intf_associated = 0; ++ rt2x00dev->intf_beaconing = 0; + + /* Enable the radio */ + retval = rt2x00lib_enable_radio(rt2x00dev); +@@ -1312,6 +1314,7 @@ void rt2x00lib_stop(struct rt2x00_dev *r + rt2x00dev->intf_ap_count = 0; + rt2x00dev->intf_sta_count = 0; + rt2x00dev->intf_associated = 0; ++ rt2x00dev->intf_beaconing = 0; + } + + static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +@@ -598,6 +598,17 @@ void rt2x00mac_bss_info_changed(struct i + */ + if (changes & BSS_CHANGED_BEACON_ENABLED) { + mutex_lock(&intf->beacon_skb_mutex); ++ ++ /* ++ * Clear the 'enable_beacon' flag and clear beacon because ++ * the beacon queue has been stopped after hardware reset. ++ */ ++ if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) && ++ intf->enable_beacon) { ++ intf->enable_beacon = false; ++ rt2x00queue_clear_beacon(rt2x00dev, vif); ++ } ++ + if (!bss_conf->enable_beacon && intf->enable_beacon) { + rt2x00dev->intf_beaconing--; + intf->enable_beacon = false; diff --git a/package/kernel/mac80211/patches/rt2x00/602-03-wifi-rt2x00-Add-support-for-loading-EEPROM-from-MTD.patch b/package/kernel/mac80211/patches/rt2x00/602-03-wifi-rt2x00-Add-support-for-loading-EEPROM-from-MTD.patch index 6a343db9c728..fab4bf39c05a 100644 --- a/package/kernel/mac80211/patches/rt2x00/602-03-wifi-rt2x00-Add-support-for-loading-EEPROM-from-MTD.patch +++ b/package/kernel/mac80211/patches/rt2x00/602-03-wifi-rt2x00-Add-support-for-loading-EEPROM-from-MTD.patch @@ -94,7 +94,7 @@ Signed-off-by: Christian Marangi static const char * rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) { -@@ -83,5 +141,13 @@ err_exit: +@@ -83,6 +141,14 @@ err_exit: int rt2x00lib_read_eeprom(struct rt2x00_dev *rt2x00dev) { @@ -108,3 +108,4 @@ Signed-off-by: Christian Marangi + return rt2x00lib_read_eeprom_file(rt2x00dev); } + EXPORT_SYMBOL_GPL(rt2x00lib_read_eeprom); diff --git a/package/kernel/mac80211/patches/rt2x00/602-05-wifi-rt2x00-support-loading-eeprom-from-NVMEM-cells.patch b/package/kernel/mac80211/patches/rt2x00/602-05-wifi-rt2x00-support-loading-eeprom-from-NVMEM-cells.patch index efe6e52720ad..e6633363bd38 100644 --- a/package/kernel/mac80211/patches/rt2x00/602-05-wifi-rt2x00-support-loading-eeprom-from-NVMEM-cells.patch +++ b/package/kernel/mac80211/patches/rt2x00/602-05-wifi-rt2x00-support-loading-eeprom-from-NVMEM-cells.patch @@ -84,7 +84,7 @@ Signed-off-by: Christian Marangi static const char * rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) { -@@ -164,5 +199,9 @@ int rt2x00lib_read_eeprom(struct rt2x00_ +@@ -164,6 +199,10 @@ int rt2x00lib_read_eeprom(struct rt2x00_ return 0; #endif @@ -94,3 +94,4 @@ Signed-off-by: Christian Marangi + return rt2x00lib_read_eeprom_file(rt2x00dev); } + EXPORT_SYMBOL_GPL(rt2x00lib_read_eeprom); diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch index ffee2189d2d3..ab09a68297fd 100644 --- a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch +++ b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -12,7 +12,7 @@ #endif /* _RT2X00_PLATFORM_H */ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1007,6 +1007,22 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -1008,6 +1008,22 @@ static int rt2x00lib_probe_hw_modes(stru unsigned int num_rates; unsigned int i; diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch index 37553bb80a07..79f99ffdf4a2 100644 --- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch +++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -989,6 +989,12 @@ static void rt2x00lib_rate(struct ieee80 +@@ -990,6 +990,12 @@ static void rt2x00lib_rate(struct ieee80 void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) { diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch index 6211809c0a0c..31f2f0261fd5 100644 --- a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch +++ b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1012,6 +1012,16 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -1013,6 +1013,16 @@ static int rt2x00lib_probe_hw_modes(stru struct ieee80211_rate *rates; unsigned int num_rates; unsigned int i; diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch index 7b50bc275e2f..8ee4e6cafa6a 100644 --- a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch +++ b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch @@ -8,7 +8,7 @@ #include "rt2x00.h" #include "rt2800lib.h" -@@ -11129,6 +11130,17 @@ static int rt2800_init_eeprom(struct rt2 +@@ -11285,6 +11286,17 @@ static int rt2800_init_eeprom(struct rt2 rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch index aa2b25ba7f5d..9564f02eddec 100644 --- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch +++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1359,7 +1359,7 @@ static inline void rt2x00lib_set_if_comb +@@ -1362,7 +1362,7 @@ static inline void rt2x00lib_set_if_comb */ if_limit = &rt2x00dev->if_limits_ap; if_limit->max = rt2x00dev->ops->max_ap_intf; diff --git a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch index 634b677722f8..3e48eab5d202 100644 --- a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch +++ b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch @@ -27,7 +27,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -304,6 +304,24 @@ static void rt2800_rf_write(struct rt2x0 +@@ -305,6 +305,24 @@ static void rt2800_rf_write(struct rt2x0 mutex_unlock(&rt2x00dev->csr_mutex); } @@ -52,67 +52,27 @@ Signed-off-by: Daniel Golle static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = { [EEPROM_CHIP_ID] = 0x0000, [EEPROM_VERSION] = 0x0001, -@@ -4469,6 +4487,29 @@ static void rt2800_config_channel(struct - rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, - 0x6C6C6B6C); - } -+ -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); -+ reg |= 0x00000101; -+ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); -+ -+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); -+ reg |= 0x00000101; -+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -+ rt2800_bbp_write(rt2x00dev, 75, 0x68); -+ rt2800_bbp_write(rt2x00dev, 76, 0x4C); -+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in -+ * config channel function in dependence of channel and -+ * HT20/HT40 so don't touch it -+ */ -+ } - } +@@ -10407,8 +10425,10 @@ static void rt2800_calibration_rt6352(st + u32 reg; - bbp = rt2800_bbp_read(rt2x00dev, 4); -@@ -10581,6 +10622,7 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); - rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + if (rt2x00_has_cap_external_pa(rt2x00dev) || +- rt2x00_has_cap_external_lna_bg(rt2x00dev)) ++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { ++ rt6352_enable_pa_pin(rt2x00dev, 0); + rt2800_restore_rf_bbp_rt6352(rt2x00dev); ++ } -+ rt6352_enable_pa_pin(rt2x00dev, 0); rt2800_r_calibration(rt2x00dev); rt2800_rf_self_txdc_cal(rt2x00dev); - rt2800_rxdcoc_calibration(rt2x00dev); -@@ -10588,6 +10630,22 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_bw_filter_calibration(rt2x00dev, false); - rt2800_loft_iq_calibration(rt2x00dev); - rt2800_rxiq_calibration(rt2x00dev); +@@ -10426,6 +10446,8 @@ static void rt2800_calibration_rt6352(st + !rt2x00_has_cap_external_lna_bg(rt2x00dev)) + return; + + rt6352_enable_pa_pin(rt2x00dev, 1); + -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -+ rt2800_bbp_write(rt2x00dev, 75, 0x68); -+ rt2800_bbp_write(rt2x00dev, 76, 0x4C); -+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config -+ * channel function in dependence of channel and HT20/HT40, -+ * so don't touch them here. -+ */ -+ } - } - - static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + if (rt2x00_has_cap_external_pa(rt2x00dev)) { + reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); + reg |= 0x00000101; --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -28,6 +28,7 @@ @@ -123,7 +83,7 @@ Signed-off-by: Daniel Golle #include #include -@@ -1024,6 +1025,11 @@ struct rt2x00_dev { +@@ -1027,6 +1028,11 @@ struct rt2x00_dev { /* Clock for System On Chip devices. */ struct clk *clk; diff --git a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch index 4b3e549109d5..0f699f5e18b0 100644 --- a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +++ b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -1044,6 +1044,11 @@ +@@ -1056,6 +1056,11 @@ #define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010) #define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020) @@ -14,7 +14,7 @@ */ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3778,14 +3778,16 @@ static void rt2800_config_channel_rf7620 +@@ -3836,14 +3836,16 @@ static void rt2800_config_channel_rf7620 rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); @@ -39,7 +39,7 @@ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, -@@ -3819,18 +3821,23 @@ static void rt2800_config_channel_rf7620 +@@ -3877,18 +3879,23 @@ static void rt2800_config_channel_rf7620 rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); } @@ -73,7 +73,7 @@ if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { if (conf_is_ht40(conf)) { -@@ -3929,25 +3936,29 @@ static void rt2800_config_alc(struct rt2 +@@ -4002,25 +4009,29 @@ static void rt2800_config_alc_rt6352(str if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n"); @@ -121,7 +121,17 @@ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); rt2800_vco_calibration(rt2x00dev); -@@ -6011,18 +6022,33 @@ static int rt2800_init_registers(struct +@@ -4513,7 +4524,8 @@ static void rt2800_config_channel(struct + if (rt2x00_rt(rt2x00dev, RT6352)) { + /* BBP for GLRT BW */ + bbp = conf_is_ht40(conf) ? +- 0x10 : rt2x00_has_cap_external_lna_bg(rt2x00dev) ? ++ 0x10 : !rt2x00_has_cap_external_lna_bg(rt2x00dev) ? ++ 0x1a : rt2800_hw_get_chippkg(rt2x00dev) == 1 ? + 0x15 : 0x1a; + rt2800_bbp_glrt_write(rt2x00dev, 141, bbp); + +@@ -6017,18 +6029,33 @@ static int rt2800_init_registers(struct } else if (rt2x00_rt(rt2x00dev, RT5350)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); } else if (rt2x00_rt(rt2x00dev, RT6352)) { @@ -167,7 +177,7 @@ reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); -@@ -7127,14 +7153,16 @@ static void rt2800_init_bbp_6352(struct +@@ -7141,14 +7168,16 @@ static void rt2800_init_bbp_6352(struct rt2800_bbp_write(rt2x00dev, 188, 0x00); rt2800_bbp_write(rt2x00dev, 189, 0x00); @@ -192,7 +202,27 @@ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); -@@ -10406,31 +10434,36 @@ static void rt2800_init_rfcsr_6352(struc +@@ -10381,6 +10410,9 @@ static void rt2800_restore_rf_bbp_rt6352 + rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0); + } + ++ if (rt2800_hw_get_chippkg(rt2x00dev) != 1) ++ return; ++ + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); + rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); +@@ -10458,6 +10490,9 @@ static void rt2800_calibration_rt6352(st + rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); + } + ++ if (rt2800_hw_get_chippkg(rt2x00dev) != 1) ++ return; ++ + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); + rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); +@@ -10548,31 +10583,36 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); rt2800_rfcsr_write(rt2x00dev, 43, 0x00); @@ -254,7 +284,7 @@ /* Initialize RF channel register to default value */ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); -@@ -10496,63 +10529,71 @@ static void rt2800_init_rfcsr_6352(struc +@@ -10638,63 +10678,71 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); @@ -288,33 +318,6 @@ - rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); - rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); - rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); -- -- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); -- -- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -- -- /* Initialize RF channel register for DRQFN */ -- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); + if (rt2800_hw_get_chipver(rt2x00dev) > 1) { + rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); + rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); @@ -347,7 +350,16 @@ + rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); + rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); + } -+ + +- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); + if (rt2800_hw_get_chipver(rt2x00dev) > 1 && + rt2800_hw_get_chipeco(rt2x00dev) >= 2) { + rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); @@ -367,7 +379,23 @@ + rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); + rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); + } -+ + +- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); +- +- /* Initialize RF channel register for DRQFN */ +- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); +- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); + if (rt2800_hw_get_chippkg(rt2x00dev) == 0 && + rt2800_hw_get_chipver(rt2x00dev) == 1) { + /* Initialize RF channel register for DRQFN */ @@ -383,7 +411,7 @@ /* Initialize RF DC calibration register to default value */ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); -@@ -10615,12 +10656,17 @@ static void rt2800_init_rfcsr_6352(struc +@@ -10757,12 +10805,17 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); @@ -404,5 +432,5 @@ + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + } - rt6352_enable_pa_pin(rt2x00dev, 0); - rt2800_r_calibration(rt2x00dev); + /* Do calibration and init PA/LNA */ + rt2800_calibration_rt6352(rt2x00dev); diff --git a/package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch b/package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch deleted file mode 100644 index 1eb5ee8aa0fa..000000000000 --- a/package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch +++ /dev/null @@ -1,413 +0,0 @@ -From: Shiji Yang -Date: Tue, 25 Jul 2023 20:05:06 +0800 -Subject: [PATCH] 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. Correct MAC_SYS_CTRL register RX mask to 0x08 in R-Calibration - function. For MAC_SYS_CTRL register, Bit[2] controls MAC_TX_EN - and Bit[3] controls MAC_RX_EN (Bit index starts from 0). -5. Move the channel configuration code from rt2800_vco_calibration() - to the rt2800_config_channel(). -6. Use MT7620 SOC specific AGC initial LNA value instead of the - RT5592's value. -7. Adjust the register operation sequence according to the vendor - driver code. This may not be useful, but it can make things - clearer when developers try to review it. - -Signed-off-by: Shiji Yang ---- - .../net/wireless/ralink/rt2x00/rt2800lib.c | 306 ++++++++++-------- - drivers/net/wireless/ralink/rt2x00/rt2x00.h | 6 + - 2 files changed, 182 insertions(+), 130 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3881,14 +3881,6 @@ static void rt2800_config_channel_rf7620 - rfcsr |= tx_agc_fc; - rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); - } -- -- if (conf_is_ht40(conf)) { -- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10); -- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f); -- } else { -- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a); -- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40); -- } - } - - static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev, -@@ -4457,89 +4449,63 @@ static void rt2800_config_channel(struct - usleep_range(1000, 1500); - } - -- if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { -+ if (rt2x00_rt(rt2x00dev, RT5592)) { - reg = 0x10; -- if (!conf_is_ht40(conf)) { -- if (rt2x00_rt(rt2x00dev, RT6352) && -- rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -- reg |= 0x5; -- } else { -- reg |= 0xa; -- } -- } -+ if (!conf_is_ht40(conf)) -+ reg |= 0xa; - rt2800_bbp_write(rt2x00dev, 195, 141); - rt2800_bbp_write(rt2x00dev, 196, reg); - -- /* AGC init. -- * Despite the vendor driver using different values here for -- * RT6352 chip, we use 0x1c for now. This may have to be changed -- * once TSSI got implemented. -- */ - reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; - rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); -- -- if (rt2x00_rt(rt2x00dev, RT5592)) -- rt2800_iq_calibrate(rt2x00dev, rf->channel); -+ -+ 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); -+ /* BBP for GLRT BW */ -+ 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); - -- 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); -+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x15); - } - -- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); -- reg |= 0x00000101; -- rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); -- -- reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); -- reg |= 0x00000101; -- rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); -- -- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -- rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -- rt2800_bbp_write(rt2x00dev, 75, 0x68); -- rt2800_bbp_write(rt2x00dev, 76, 0x4C); -- rt2800_bbp_write(rt2x00dev, 79, 0x1C); -- rt2800_bbp_write(rt2x00dev, 80, 0x0C); -- rt2800_bbp_write(rt2x00dev, 82, 0xB6); -- /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in -- * config channel function in dependence of channel and -- * HT20/HT40 so don't touch it -- */ -+ if (rt2x00dev->default_ant.rx_chain_num == 1) { -+ rt2800_bbp_write(rt2x00dev, 91, 0x07); -+ rt2800_bbp_write(rt2x00dev, 95, 0x1A); -+ rt2800_bbp_write(rt2x00dev, 195, 128); -+ rt2800_bbp_write(rt2x00dev, 196, 0xA0); -+ rt2800_bbp_write(rt2x00dev, 195, 170); -+ rt2800_bbp_write(rt2x00dev, 196, 0x12); -+ rt2800_bbp_write(rt2x00dev, 195, 171); -+ rt2800_bbp_write(rt2x00dev, 196, 0x10); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 91, 0x06); -+ rt2800_bbp_write(rt2x00dev, 95, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 195, 128); -+ rt2800_bbp_write(rt2x00dev, 196, 0xE0); -+ rt2800_bbp_write(rt2x00dev, 195, 170); -+ rt2800_bbp_write(rt2x00dev, 196, 0x30); -+ rt2800_bbp_write(rt2x00dev, 195, 171); -+ rt2800_bbp_write(rt2x00dev, 196, 0x30); - } -+ -+ /* AGC init */ -+ reg = rf->channel <= 14 ? 0x04 + 2 * rt2x00dev->lna_gain : 0; -+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); -+ -+ /* On 11A, We should delay and wait RF/BBP to be stable -+ * and the appropriate time should be 1000 micro seconds -+ * 2005/06/05 - On 11G, we also need this delay time. -+ * Otherwise it's difficult to pass the WHQL. -+ */ -+ usleep_range(1000, 1500); - } - - bbp = rt2800_bbp_read(rt2x00dev, 4); -@@ -5649,43 +5615,6 @@ void rt2800_vco_calibration(struct rt2x0 - } - } - rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); -- -- if (rt2x00_rt(rt2x00dev, RT6352)) { -- if (rt2x00dev->default_ant.rx_chain_num == 1) { -- rt2800_bbp_write(rt2x00dev, 91, 0x07); -- rt2800_bbp_write(rt2x00dev, 95, 0x1A); -- rt2800_bbp_write(rt2x00dev, 195, 128); -- rt2800_bbp_write(rt2x00dev, 196, 0xA0); -- rt2800_bbp_write(rt2x00dev, 195, 170); -- rt2800_bbp_write(rt2x00dev, 196, 0x12); -- rt2800_bbp_write(rt2x00dev, 195, 171); -- rt2800_bbp_write(rt2x00dev, 196, 0x10); -- } else { -- rt2800_bbp_write(rt2x00dev, 91, 0x06); -- rt2800_bbp_write(rt2x00dev, 95, 0x9A); -- rt2800_bbp_write(rt2x00dev, 195, 128); -- rt2800_bbp_write(rt2x00dev, 196, 0xE0); -- rt2800_bbp_write(rt2x00dev, 195, 170); -- rt2800_bbp_write(rt2x00dev, 196, 0x30); -- rt2800_bbp_write(rt2x00dev, 195, 171); -- rt2800_bbp_write(rt2x00dev, 196, 0x30); -- } -- -- 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); -- } -- -- /* On 11A, We should delay and wait RF/BBP to be stable -- * and the appropriate time should be 1000 micro seconds -- * 2005/06/05 - On 11G, we also need this delay time. -- * Otherwise it's difficult to pass the WHQL. -- */ -- usleep_range(1000, 1500); -- } - } - EXPORT_SYMBOL_GPL(rt2800_vco_calibration); - -@@ -8650,7 +8579,7 @@ static void rt2800_r_calibration(struct - rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n"); - - maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); -- maccfg &= (~0x04); -+ maccfg &= (~0x08); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg); - - if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX))) -@@ -10686,30 +10615,143 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); - rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); - } -+} - -- rt6352_enable_pa_pin(rt2x00dev, 0); -- rt2800_r_calibration(rt2x00dev); -- rt2800_rf_self_txdc_cal(rt2x00dev); -- rt2800_rxdcoc_calibration(rt2x00dev); -- rt2800_bw_filter_calibration(rt2x00dev, true); -- rt2800_bw_filter_calibration(rt2x00dev, false); -- rt2800_loft_iq_calibration(rt2x00dev); -- rt2800_rxiq_calibration(rt2x00dev); -- rt6352_enable_pa_pin(rt2x00dev, 1); -+static void rt2800_init_palna_rt6352(struct rt2x00_dev *rt2x00dev) -+{ -+ u32 reg; -+ -+ 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)) { -+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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 (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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 (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ rt2x00_has_cap_external_pa(rt2x00dev)) -+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00); -+ -+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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); -- /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config -- * channel function in dependence of channel and HT20/HT40, -- * so don't touch them here. -- */ -+ } -+ -+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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_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 (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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 (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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 (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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 (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -+ 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) -+{ -+ if (rt2x00_has_cap_external_pa(rt2x00dev) || -+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt6352_enable_pa_pin(rt2x00dev, 0); -+ 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 devices using internal PA */ -+ -+ rt2800_rxdcoc_calibration(rt2x00dev); -+ rt2800_rxiq_calibration(rt2x00dev); -+ -+ if (rt2x00_has_cap_external_pa(rt2x00dev) || -+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt6352_enable_pa_pin(rt2x00dev, 1); -+ rt2800_init_palna_rt6352(rt2x00dev); - } - } - -@@ -10802,6 +10844,10 @@ int rt2800_enable_radio(struct rt2x00_de - rt2800_init_bbp(rt2x00dev); - rt2800_init_rfcsr(rt2x00dev); - -+ /* Do calibration and init PA/LNA for RT6352 */ -+ if (rt2x00_rt(rt2x00dev, RT6352)) -+ rt2800_calibration_rt6352(rt2x00dev); -+ - if (rt2x00_is_usb(rt2x00dev) && - (rt2x00_rt(rt2x00dev, RT3070) || - rt2x00_rt(rt2x00dev, RT3071) || ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -1272,6 +1272,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); -- 2.30.2