summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorKalle Valo <kvalo@kernel.org>2024-11-11 12:07:21 +0100
committerKalle Valo <kvalo@kernel.org>2024-11-11 12:07:21 +0100
commit5255ee958f584c86b9f4836bf750073a36fc3c02 (patch)
tree876ccf1d82e5c5a2d3d6fcefe6bc81dd42b135b2 /drivers/net/wireless
parentwifi: iwlwifi: mvm: don't call power_update_mac in fast suspend (diff)
parentwifi: rtlwifi: Remove some exhalbtc deadcode (diff)
downloadlinux-5255ee958f584c86b9f4836bf750073a36fc3c02.tar.xz
linux-5255ee958f584c86b9f4836bf750073a36fc3c02.zip
Merge tag 'rtw-next-2024-11-06' of https://github.com/pkshih/rtw
rtw-next patches for v6.13 Major changes are listed: rtw88: - support two USB adapters 8821au and 8812au rtw89: - add thermal protection - fine tune BT-coexsitence to improve user experience - firmware secure boot for WiFi 6 chip - more materials for MLO
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c11
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h1
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c79
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h10
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/efuse.c11
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c3
-rw-r--r--drivers/net/wireless/realtek/rtw88/Kconfig33
-rw-r--r--drivers/net/wireless/realtek/rtw88/Makefile15
-rw-r--r--drivers/net/wireless/realtek/rtw88/coex.c37
-rw-r--r--drivers/net/wireless/realtek/rtw88/coex.h11
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.c2
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.c44
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.h17
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac.c13
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac.h3
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.c35
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.h39
-rw-r--r--drivers/net/wireless/realtek/rtw88/pci.c2
-rw-r--r--drivers/net/wireless/realtek/rtw88/phy.c80
-rw-r--r--drivers/net/wireless/realtek/rtw88/reg.h174
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8703b.c21
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8723d.c21
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8723x.c3
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8812a.c1102
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8812a.h10
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8812a_table.c2812
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8812a_table.h26
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8812au.c28
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821a.c1197
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821a.h10
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821a_table.c2350
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821a_table.h21
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821au.c28
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c.c22
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c.h24
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822b.c20
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822b.h12
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822c.c28
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw88xxa.c1989
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw88xxa.h175
-rw-r--r--drivers/net/wireless/realtek/rtw88/rx.c12
-rw-r--r--drivers/net/wireless/realtek/rtw88/sdio.c2
-rw-r--r--drivers/net/wireless/realtek/rtw88/tx.c6
-rw-r--r--drivers/net/wireless/realtek/rtw88/tx.h4
-rw-r--r--drivers/net/wireless/realtek/rtw88/usb.c5
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.c51
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.h24
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.c183
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.h8
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.c10
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.c188
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h62
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.c10
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse.c150
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse.h2
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse_be.c52
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c190
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h23
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c40
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h13
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c3
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac_be.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c37
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.h15
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c34
-rw-r--r--drivers/net/wireless/realtek/rtw89/reg.h2
-rw-r--r--drivers/net/wireless/realtek/rtw89/regd.c32
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b.c5
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851be.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.c1
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852ae.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b.c5
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b_common.c8
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852be.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt.c5
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bte.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.c5
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c6
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852ce.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a.c88
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c61
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922ae.c8
-rw-r--r--drivers/net/wireless/realtek/rtw89/sar.c6
84 files changed, 11390 insertions, 500 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
index 039bbedb41c2..379193b24428 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
@@ -3409,17 +3409,6 @@ void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
}
}
-void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist)
-{
- struct rtl_priv *rtlpriv = btcoexist->adapter;
-
- rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], *****************Coex DM Reset****************\n");
-
- halbtc8723b1ant_init_hw_config(btcoexist, false, false);
- halbtc8723b1ant_init_coex_dm(btcoexist);
-}
-
void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h
index 9d41e11388ad..a4506d838dc7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h
@@ -197,7 +197,6 @@ void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist);
void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate);
-void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist);
void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist);
void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist,
struct seq_file *m);
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index be4c0e60d44d..478cca33e5e3 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -1708,19 +1708,6 @@ void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
halbtc_normal_low_power(btcoexist);
}
-void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
-{
- if (!halbtc_is_bt_coexist_available(btcoexist))
- return;
-
- if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
- } else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
- if (btcoexist->board_info.btdm_ant_num == 1)
- ex_btc8723b1ant_rf_status_notify(btcoexist, type);
- } else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
- }
-}
-
void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
@@ -1768,31 +1755,6 @@ void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
}
}
-void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist)
-{
- struct rtl_priv *rtlpriv = btcoexist->adapter;
-
- if (!halbtc_is_bt_coexist_available(btcoexist))
- return;
- btcoexist->statistics.cnt_coex_dm_switch++;
-
- halbtc_leave_low_power(btcoexist);
-
- if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
- if (btcoexist->board_info.btdm_ant_num == 1) {
- btcoexist->stop_coex_dm = true;
- ex_btc8723b1ant_coex_dm_reset(btcoexist);
- exhalbtc_set_ant_num(rtlpriv,
- BT_COEX_ANT_TYPE_DETECTED, 2);
- ex_btc8723b2ant_init_hwconfig(btcoexist);
- ex_btc8723b2ant_init_coex_dm(btcoexist);
- btcoexist->stop_coex_dm = false;
- }
- }
-
- halbtc_normal_low_power(btcoexist);
-}
-
void exhalbtc_periodical(struct btc_coexist *btcoexist)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
@@ -1820,29 +1782,6 @@ void exhalbtc_periodical(struct btc_coexist *btcoexist)
halbtc_normal_low_power(btcoexist);
}
-void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
- u8 code, u8 len, u8 *data)
-{
- if (!halbtc_is_bt_coexist_available(btcoexist))
- return;
- btcoexist->statistics.cnt_dbg_ctrl++;
-
- halbtc_leave_low_power(btcoexist);
-
- halbtc_normal_low_power(btcoexist);
-}
-
-void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
- u32 offset, u32 span, u32 seconds)
-{
- if (!halbtc_is_bt_coexist_available(btcoexist))
- return;
-}
-
-void exhalbtc_stack_update_profile_info(void)
-{
-}
-
void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
@@ -1851,24 +1790,6 @@ void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
btcoexist->stack_info.min_bt_rssi = bt_rssi;
}
-void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version)
-{
- if (!halbtc_is_bt_coexist_available(btcoexist))
- return;
-
- btcoexist->stack_info.hci_version = hci_version;
-}
-
-void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
- u16 bt_hci_version, u16 bt_patch_version)
-{
- if (!halbtc_is_bt_coexist_available(btcoexist))
- return;
-
- btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
- btcoexist->bt_info.bt_hci_ver = bt_hci_version;
-}
-
void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type)
{
switch (chip_type) {
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
index a96a995dd850..d8d88a989806 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -763,19 +763,9 @@ void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
u8 length);
-void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type);
void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
-void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist);
void exhalbtc_periodical(struct btc_coexist *btcoexist);
-void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
- u8 *data);
-void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
- u32 offset, u32 span, u32 seconds);
-void exhalbtc_stack_update_profile_info(void);
-void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version);
-void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
- u16 bt_hci_version, u16 bt_patch_version);
void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi);
void exhalbtc_set_bt_exist(struct btc_coexist *btcoexist, bool bt_exist);
void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type);
diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c
index 82cf5fb5175f..6518e77b89f5 100644
--- a/drivers/net/wireless/realtek/rtlwifi/efuse.c
+++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c
@@ -162,10 +162,19 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 max_attempts = 10000;
u32 value32;
u8 readbyte;
u16 retry;
+ /*
+ * In case of USB devices, transfer speeds are limited, hence
+ * efuse I/O reads could be (way) slower. So, decrease (a lot)
+ * the read attempts in case of failures.
+ */
+ if (rtlpriv->rtlhal.interface == INTF_USB)
+ max_attempts = 10;
+
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
(_offset & 0xff));
readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
@@ -178,7 +187,7 @@ void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
retry = 0;
value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
- while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
+ while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < max_attempts)) {
value32 = rtl_read_dword(rtlpriv,
rtlpriv->cfg->maps[EFUSE_CTRL]);
retry++;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
index 1b144fbd4d26..048744166a92 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
@@ -350,7 +350,8 @@ MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
-MODULE_FIRMWARE("rtlwifi/rtl8723efw.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723fw.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723fw_B.bin");
module_param_named(swenc, rtl8723e_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8723e_mod_params.debug_level, int, 0644);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
index a65503c5ae5a..b5266e560416 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
@@ -407,6 +407,9 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw_29.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8821aefw_wowlan.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8812aefw.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8812aefw_wowlan.bin");
module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644);
diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 02b0d698413b..733b3e58da51 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -43,6 +43,17 @@ config RTW88_8723D
config RTW88_8821C
tristate
+config RTW88_88XXA
+ tristate
+
+config RTW88_8821A
+ tristate
+ select RTW88_88XXA
+
+config RTW88_8812A
+ tristate
+ select RTW88_88XXA
+
config RTW88_8822BE
tristate "Realtek 8822BE PCI wireless network adapter"
depends on PCI
@@ -189,6 +200,28 @@ config RTW88_8821CU
802.11ac USB wireless network adapter
+config RTW88_8821AU
+ tristate "Realtek 8821AU/8811AU USB wireless network adapter"
+ depends on USB
+ select RTW88_CORE
+ select RTW88_USB
+ select RTW88_8821A
+ help
+ Select this option will enable support for 8821AU and 8811AU chipset
+
+ 802.11ac USB wireless network adapter
+
+config RTW88_8812AU
+ tristate "Realtek 8812AU USB wireless network adapter"
+ depends on USB
+ select RTW88_CORE
+ select RTW88_USB
+ select RTW88_8812A
+ help
+ Select this option will enable support for 8812AU chipset
+
+ 802.11ac USB wireless network adapter
+
config RTW88_DEBUG
bool "Realtek rtw88 debug support"
depends on RTW88_CORE
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 8f47359b4380..f0b49f5a8a5a 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -77,6 +77,21 @@ rtw88_8821cs-objs := rtw8821cs.o
obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o
rtw88_8821cu-objs := rtw8821cu.o
+obj-$(CONFIG_RTW88_88XXA) += rtw88_88xxa.o
+rtw88_88xxa-objs := rtw88xxa.o
+
+obj-$(CONFIG_RTW88_8821A) += rtw88_8821a.o
+rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o
+
+obj-$(CONFIG_RTW88_8812A) += rtw88_8812a.o
+rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o
+
+obj-$(CONFIG_RTW88_8821AU) += rtw88_8821au.o
+rtw88_8821au-objs := rtw8821au.o
+
+obj-$(CONFIG_RTW88_8812AU) += rtw88_8812au.o
+rtw88_8812au-objs := rtw8812au.o
+
obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
rtw88_pci-objs := pci.o
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index a99776af56c2..c929db1e53ca 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -446,7 +446,7 @@ static void rtw_coex_check_rfk(struct rtw_dev *rtwdev)
}
}
-static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
+void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
{
struct rtw_coex *coex = &rtwdev->coex;
struct rtw_coex_stat *coex_stat = &coex->stat;
@@ -494,11 +494,29 @@ static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev)
struct rtw_coex_stat *coex_stat = &coex->stat;
struct rtw_coex_dm *coex_dm = &coex->dm;
bool bt_disabled = false;
+ bool bt_active = true;
u16 score_board;
if (chip->scbd_support) {
score_board = rtw_coex_read_scbd(rtwdev);
bt_disabled = !(score_board & COEX_SCBD_ONOFF);
+ } else {
+ if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 &&
+ coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0)
+ bt_active = false;
+
+ if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff &&
+ coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff)
+ bt_active = false;
+
+ if (bt_active) {
+ coex_stat->bt_disable_cnt = 0;
+ bt_disabled = false;
+ } else {
+ coex_stat->bt_disable_cnt++;
+ if (coex_stat->bt_disable_cnt >= 10)
+ bt_disabled = true;
+ }
}
if (coex_stat->bt_disabled != bt_disabled) {
@@ -950,12 +968,18 @@ static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control)
static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)
{
+ if (!rtwdev->chip->ltecoex_addr)
+ return;
+
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state);
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state);
}
static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state)
{
+ if (!rtwdev->chip->ltecoex_addr)
+ return;
+
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state);
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state);
}
@@ -2747,16 +2771,19 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)
rtw_write8(rtwdev, 0xff1a, 0x0);
rtw_coex_set_gnt_debug(rtwdev);
}
+EXPORT_SYMBOL(rtw_coex_power_on_setting);
void rtw_coex_power_off_setting(struct rtw_dev *rtwdev)
{
rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN);
}
+EXPORT_SYMBOL(rtw_coex_power_off_setting);
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
{
__rtw_coex_init_hw_config(rtwdev, wifi_only);
}
+EXPORT_SYMBOL(rtw_coex_init_hw_config);
void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type)
{
@@ -3904,7 +3931,7 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
u8 sys_lte;
u16 score_board_WB, score_board_BW;
u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc;
- u32 lte_coex, bt_coex;
+ u32 lte_coex = 0, bt_coex = 0;
int i;
score_board_BW = rtw_coex_read_scbd(rtwdev);
@@ -3916,8 +3943,10 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL);
sys_lte = rtw_read8(rtwdev, 0x73);
- lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
- bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
+ if (rtwdev->chip->ltecoex_addr) {
+ lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
+ bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
+ }
if (!coex_stat->wl_under_ips &&
(!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) &&
diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h
index 57cf29da9ea4..c398be8391f7 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.h
+++ b/drivers/net/wireless/realtek/rtw88/coex.h
@@ -384,6 +384,7 @@ u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr);
void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
u32 mask, u32 val);
void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);
+void rtw_coex_query_bt_info(struct rtw_dev *rtwdev);
void rtw_coex_bt_relink_work(struct work_struct *work);
void rtw_coex_bt_reenable_work(struct work_struct *work);
@@ -419,4 +420,14 @@ static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev)
return coex_stat->bt_disabled;
}
+static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev)
+{
+ /* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself
+ * when bluetooth headphones are disconnected, so we have to
+ * ask for it regularly.
+ */
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex)
+ rtw_coex_query_bt_info(rtwdev);
+}
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index c26a6905fd15..364ec0436d0f 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -308,7 +308,7 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
{
struct rtw_debugfs_priv *debugfs_priv = m->private;
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
- u8 page_size = rtwdev->chip->page_size;
+ u16 page_size = rtwdev->chip->page_size;
u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;
u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;
u8 *buf;
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 813c12148819..e6e9946fbf44 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -139,25 +139,30 @@ static u16 get_max_amsdu_len(u32 bit_rate)
struct rtw_fw_iter_ra_data {
struct rtw_dev *rtwdev;
u8 *payload;
+ u8 length;
};
static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw_fw_iter_ra_data *ra_data = data;
+ struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload;
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
u8 mac_id, rate, sgi, bw;
u8 mcs, nss;
u32 bit_rate;
- mac_id = GET_RA_REPORT_MACID(ra_data->payload);
+ mac_id = ra_rpt->mac_id;
if (si->mac_id != mac_id)
return;
si->ra_report.txrate.flags = 0;
- rate = GET_RA_REPORT_RATE(ra_data->payload);
- sgi = GET_RA_REPORT_SGI(ra_data->payload);
- bw = GET_RA_REPORT_BW(ra_data->payload);
+ rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE);
+ sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI);
+ if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw))
+ bw = ra_rpt->bw;
+ else
+ bw = si->bw_mode;
if (rate < DESC_RATEMCS0) {
si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate);
@@ -197,14 +202,18 @@ legacy:
static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload,
u8 length)
{
+ struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload;
struct rtw_fw_iter_ra_data ra_data;
- if (WARN(length < 7, "invalid ra report c2h length\n"))
+ if (WARN(length < rtwdev->chip->c2h_ra_report_size,
+ "invalid ra report c2h length %d\n", length))
return;
- rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload);
+ rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi,
+ RTW_C2H_RA_RPT_RATE);
ra_data.rtwdev = rtwdev;
ra_data.payload = payload;
+ ra_data.length = length;
rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data);
}
@@ -1281,16 +1290,16 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb,
rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
- rtw_tx_fill_tx_desc(&pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb);
}
-static inline u8 rtw_len_to_page(unsigned int len, u8 page_size)
+static inline u8 rtw_len_to_page(unsigned int len, u16 page_size)
{
return DIV_ROUND_UP(len, page_size);
}
-static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size,
- u8 page_margin, u32 page, u8 *buf,
+static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size,
+ u16 page_margin, u32 page, u8 *buf,
struct rtw_rsvd_page *rsvd_pkt)
{
struct sk_buff *skb = rsvd_pkt->skb;
@@ -1592,13 +1601,13 @@ static int __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev)
static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size)
{
- struct ieee80211_hw *hw = rtwdev->hw;
const struct rtw_chip_info *chip = rtwdev->chip;
- struct sk_buff *iter;
+ struct ieee80211_hw *hw = rtwdev->hw;
struct rtw_rsvd_page *rsvd_pkt;
- u32 page = 0;
+ struct sk_buff *iter;
+ u16 page_size, page_margin, tx_desc_sz;
u8 total_page = 0;
- u8 page_size, page_margin, tx_desc_sz;
+ u32 page = 0;
u8 *buf;
int ret;
@@ -2004,12 +2013,13 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes,
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct sk_buff *skb, *tmp;
- u8 page_offset = 1, *buf, page_size = chip->page_size;
u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc;
- u16 buf_offset = page_size * page_offset;
u8 tx_desc_sz = chip->tx_pkt_desc_sz;
- u8 page_cnt, pages;
+ u16 page_size = chip->page_size;
+ u8 page_offset = 1, *buf;
+ u16 buf_offset = page_size * page_offset;
unsigned int pkt_len;
+ u8 page_cnt, pages;
int ret;
if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM))
diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h
index e999c24e4634..404de1b0c407 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.h
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
@@ -85,6 +85,19 @@ struct rtw_c2h_adaptivity {
u8 option;
} __packed;
+struct rtw_c2h_ra_rpt {
+ u8 rate_sgi;
+ u8 mac_id;
+ u8 byte2;
+ u8 status;
+ u8 byte4;
+ u8 ra_ratio;
+ u8 bw;
+} __packed;
+
+#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0)
+#define RTW_C2H_RA_RPT_SGI BIT(7)
+
struct rtw_h2c_register {
u32 w0;
u32 w1;
@@ -364,10 +377,6 @@ struct rtw_fw_hdr_legacy {
#define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2])
#define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3])
#define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4])
-#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f)
-#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7)
-#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6])
-#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1])
#define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf)
#define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10)
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index e5abcc20b63c..cae9cca6dca3 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -227,8 +227,8 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,
return 0;
}
-static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
- const struct rtw_pwr_seq_cmd * const *cmd_seq)
+int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
+ const struct rtw_pwr_seq_cmd * const *cmd_seq)
{
u8 cut_mask;
u8 intf_mask;
@@ -267,6 +267,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
return 0;
}
+EXPORT_SYMBOL(rtw_pwr_seq_parser);
static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
{
@@ -994,6 +995,7 @@ int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
return 0;
}
+EXPORT_SYMBOL(rtw_download_firmware);
static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues)
{
@@ -1127,7 +1129,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
return 0;
}
-static int set_trx_fifo_info(struct rtw_dev *rtwdev)
+int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fifo_conf *fifo = &rtwdev->fifo;
@@ -1136,7 +1138,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
/* config rsvd page num */
fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num;
- fifo->txff_pg_num = chip->txff_size >> 7;
+ fifo->txff_pg_num = chip->txff_size / chip->page_size;
if (rtw_chip_wcpu_11n(rtwdev))
fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num;
else
@@ -1179,6 +1181,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
return 0;
}
+EXPORT_SYMBOL(rtw_set_trx_fifo_info);
static int __priority_queue_cfg(struct rtw_dev *rtwdev,
const struct rtw_page_table *pg_tbl,
@@ -1256,7 +1259,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev)
u16 pubq_num;
int ret;
- ret = set_trx_fifo_info(rtwdev);
+ ret = rtw_set_trx_fifo_info(rtwdev);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/realtek/rtw88/mac.h
index 58c3dccc14bb..6905e2747372 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.h
+++ b/drivers/net/wireless/realtek/rtw88/mac.h
@@ -30,11 +30,14 @@
void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_ch_idx);
+int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
+ const struct rtw_pwr_seq_cmd * const *cmd_seq);
int rtw_mac_power_on(struct rtw_dev *rtwdev);
void rtw_mac_power_off(struct rtw_dev *rtwdev);
int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw);
int rtw_mac_init(struct rtw_dev *rtwdev);
void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop);
+int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev);
int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size);
static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index bbdef38c7e34..e91530ed05a0 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -202,6 +202,21 @@ static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif)
rtwvif->stats.rx_cnt = 0;
}
+static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev,
+ struct rtw_vif *rtwvif, int received_beacons)
+{
+ int watchdog_delay = 2000000 / 1024; /* TU */
+ int beacon_int, expected_beacons;
+
+ if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif)
+ return;
+
+ beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int;
+ expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int);
+
+ rtwdev->beacon_loss = received_beacons < expected_beacons / 2;
+}
+
/* process TX/RX statistics periodically for hardware,
* the information helps hardware to enhance performance
*/
@@ -212,6 +227,7 @@ static void rtw_watch_dog_work(struct work_struct *work)
struct rtw_traffic_stats *stats = &rtwdev->stats;
struct rtw_watch_dog_iter_data data = {};
bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
+ int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt;
u32 tx_unicast_mbps, rx_unicast_mbps;
bool ps_active;
@@ -258,6 +274,7 @@ static void rtw_watch_dog_work(struct work_struct *work)
rtw_leave_lps(rtwdev);
rtw_coex_wl_status_check(rtwdev);
rtw_coex_query_bt_hid_list(rtwdev);
+ rtw_coex_active_query_bt_info(rtwdev);
rtw_phy_dynamic_mechanism(rtwdev);
@@ -270,6 +287,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
*/
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
+ rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons);
+
/* fw supports only one station associated to enter lps, if there are
* more than two stations associated to the AP, then we can not enter
* lps, because fw does not handle the overlapped beacon interval
@@ -1309,7 +1328,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask);
}
-static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
+int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fw_state *fw;
@@ -1329,6 +1348,7 @@ static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
return ret;
}
+EXPORT_SYMBOL(rtw_wait_firmware_completion);
static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
struct rtw_fw_state *fw)
@@ -1350,7 +1370,7 @@ static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
return LPS_DEEP_MODE_NONE;
}
-static int rtw_power_on(struct rtw_dev *rtwdev)
+int rtw_power_on(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fw_state *fw = &rtwdev->fw;
@@ -1413,6 +1433,7 @@ err_off:
err:
return ret;
}
+EXPORT_SYMBOL(rtw_power_on);
void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
{
@@ -1485,7 +1506,7 @@ int rtw_core_start(struct rtw_dev *rtwdev)
{
int ret;
- ret = rtw_power_on(rtwdev);
+ ret = rtwdev->chip->ops->power_on(rtwdev);
if (ret)
return ret;
@@ -1505,12 +1526,13 @@ int rtw_core_start(struct rtw_dev *rtwdev)
return 0;
}
-static void rtw_power_off(struct rtw_dev *rtwdev)
+void rtw_power_off(struct rtw_dev *rtwdev)
{
rtw_hci_stop(rtwdev);
rtw_coex_power_off_setting(rtwdev);
rtw_mac_power_off(rtwdev);
}
+EXPORT_SYMBOL(rtw_power_off);
void rtw_core_stop(struct rtw_dev *rtwdev)
{
@@ -1535,7 +1557,7 @@ void rtw_core_stop(struct rtw_dev *rtwdev)
mutex_lock(&rtwdev->mutex);
- rtw_power_off(rtwdev);
+ rtwdev->chip->ops->power_off(rtwdev);
}
static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
@@ -1917,6 +1939,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
u8 bw;
int i;
+ if (!rtwdev->chip->hw_feature_report)
+ return 0;
+
id = rtw_read8(rtwdev, REG_C2HEVT);
if (id != C2H_HW_FEATURE_REPORT) {
rtw_err(rtwdev, "failed to read hw feature report\n");
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 05cfb235f272..cd09fb6f7b8b 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -189,6 +189,8 @@ enum rtw_chip_type {
RTW_CHIP_TYPE_8723D,
RTW_CHIP_TYPE_8821C,
RTW_CHIP_TYPE_8703B,
+ RTW_CHIP_TYPE_8821A,
+ RTW_CHIP_TYPE_8812A,
};
enum rtw_tx_queue_type {
@@ -841,6 +843,8 @@ struct rtw_regd {
};
struct rtw_chip_ops {
+ int (*power_on)(struct rtw_dev *rtwdev);
+ void (*power_off)(struct rtw_dev *rtwdev);
int (*mac_init)(struct rtw_dev *rtwdev);
int (*dump_fw_crash)(struct rtw_dev *rtwdev);
void (*shutdown)(struct rtw_dev *rtwdev);
@@ -1095,17 +1099,20 @@ enum rtw_rfe_fem {
struct rtw_rfe_def {
const struct rtw_table *phy_pg_tbl;
const struct rtw_table *txpwr_lmt_tbl;
+ const struct rtw_pwr_track_tbl *pwr_track_tbl;
const struct rtw_table *agc_btg_tbl;
};
-#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \
+#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \
.phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \
.txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
+ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \
}
-#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, btg) { \
+#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \
.phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \
.txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
+ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \
.agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \
}
@@ -1183,7 +1190,7 @@ struct rtw_chip_info {
u32 fw_rxff_size;
u16 rsvd_drv_pg_num;
u8 band;
- u8 page_size;
+ u16 page_size;
u8 csi_buf_pg_num;
u8 dig_max;
u8 dig_min;
@@ -1198,6 +1205,9 @@ struct rtw_chip_info {
const struct rtw_fwcd_segs *fwcd_segs;
u8 usb_tx_agg_desc_num;
+ bool hw_feature_report;
+ u8 c2h_ra_report_size;
+ bool old_datarate_fb_limit;
u8 default_1ss_tx_path;
@@ -1236,7 +1246,6 @@ struct rtw_chip_info {
u16 dpd_ratemask;
u8 iqk_threshold;
u8 lck_threshold;
- const struct rtw_pwr_track_tbl *pwr_track_tbl;
u8 bfer_su_max_num;
u8 bfer_mu_max_num;
@@ -1485,6 +1494,7 @@ struct rtw_coex_stat {
u8 bt_hid_slot;
u8 bt_a2dp_bitpool;
u8 bt_iqk_state;
+ u8 bt_disable_cnt;
u16 wl_beacon_interval;
u8 wl_noisy_level;
@@ -1708,7 +1718,7 @@ struct rtw_dm_info {
bool pwr_trk_init_trigger;
struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX];
s8 txagc_remnant_cck;
- s8 txagc_remnant_ofdm;
+ s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX];
u8 rx_cck_agc_report_type;
/* backup dack results for each path and I/Q */
@@ -1831,6 +1841,20 @@ struct rtw_phy_cond {
#define BRANCH_ENDIF 3
};
+struct rtw_phy_cond2 {
+#ifdef __LITTLE_ENDIAN
+ u8 type_glna;
+ u8 type_gpa;
+ u8 type_alna;
+ u8 type_apa;
+#else
+ u8 type_apa;
+ u8 type_alna;
+ u8 type_gpa;
+ u8 type_glna;
+#endif
+};
+
struct rtw_fifo_conf {
/* tx fifo information */
u16 rsvd_boundary;
@@ -1912,6 +1936,7 @@ struct rtw_hal {
u8 oem_id;
u8 pkg_type;
struct rtw_phy_cond phy_cond;
+ struct rtw_phy_cond2 phy_cond2;
bool rfe_btg;
u8 ps_mode;
@@ -1934,6 +1959,7 @@ struct rtw_hal {
u32 antenna_rx;
u8 bfee_sts_cap;
bool txrx_1ss;
+ bool cck_high_power;
/* protect tx power section */
struct mutex tx_power_mutex;
@@ -2189,6 +2215,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
bool hw_scan);
int rtw_core_start(struct rtw_dev *rtwdev);
+void rtw_power_off(struct rtw_dev *rtwdev);
void rtw_core_stop(struct rtw_dev *rtwdev);
int rtw_chip_info_setup(struct rtw_dev *rtwdev);
int rtw_core_init(struct rtw_dev *rtwdev);
@@ -2203,6 +2230,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
bool fw_exist);
void rtw_fw_recovery(struct rtw_dev *rtwdev);
+int rtw_wait_firmware_completion(struct rtw_dev *rtwdev);
+int rtw_power_on(struct rtw_dev *rtwdev);
void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start);
int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size,
u32 fwcd_item);
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index f71e41d6f97c..0ecaefc4c83d 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -824,7 +824,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev,
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, tx_pkt_desc_sz);
pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue);
- rtw_tx_fill_tx_desc(pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(&rtwpci->pdev->dev, dma))
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index d57a2aabd89b..8ed20c89d216 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -18,7 +18,10 @@ struct phy_cfg_pair {
};
union phy_table_tile {
- struct rtw_phy_cond cond;
+ struct {
+ struct rtw_phy_cond cond;
+ struct rtw_phy_cond2 cond2;
+ } __packed;
struct phy_cfg_pair cfg;
};
@@ -527,6 +530,13 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev)
*/
rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt);
+ /* Mitigate beacon loss and connectivity issues, mainly (only?)
+ * in the 5 GHz band
+ */
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss &&
+ linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH)
+ cur_igi = DIG_CVRG_MIN;
+
if (cur_igi != pre_igi)
rtw_phy_dig_write(rtwdev, cur_igi);
}
@@ -1041,7 +1051,8 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
{
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_efuse *efuse = &rtwdev->efuse;
- struct rtw_phy_cond cond = {0};
+ struct rtw_phy_cond cond = {};
+ struct rtw_phy_cond2 cond2 = {};
cond.cut = hal->cut_version ? hal->cut_version : 15;
cond.pkg = pkg ? pkg : 15;
@@ -1061,15 +1072,34 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
break;
}
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A ||
+ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
+ cond.rfe = 0;
+ cond.rfe |= efuse->ext_lna_2g;
+ cond.rfe |= efuse->ext_pa_2g << 1;
+ cond.rfe |= efuse->ext_lna_5g << 2;
+ cond.rfe |= efuse->ext_pa_5g << 3;
+ cond.rfe |= efuse->btcoex << 4;
+
+ cond2.type_alna = efuse->alna_type;
+ cond2.type_glna = efuse->glna_type;
+ cond2.type_apa = efuse->apa_type;
+ cond2.type_gpa = efuse->gpa_type;
+ }
+
hal->phy_cond = cond;
+ hal->phy_cond2 = cond2;
- rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond));
+ rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n",
+ *((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2));
}
-static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
+static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond,
+ struct rtw_phy_cond2 cond2)
{
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_phy_cond drv_cond = hal->phy_cond;
+ struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2;
if (cond.cut && cond.cut != drv_cond.cut)
return false;
@@ -1080,8 +1110,29 @@ static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
if (cond.intf && cond.intf != drv_cond.intf)
return false;
- if (cond.rfe != drv_cond.rfe)
- return false;
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A ||
+ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
+ if (!(cond.rfe & 0x0f))
+ return true;
+
+ if ((cond.rfe & drv_cond.rfe) != cond.rfe)
+ return false;
+
+ if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna)
+ return false;
+
+ if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa)
+ return false;
+
+ if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna)
+ return false;
+
+ if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa)
+ return false;
+ } else {
+ if (cond.rfe != drv_cond.rfe)
+ return false;
+ }
return true;
}
@@ -1090,7 +1141,8 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
{
const union phy_table_tile *p = tbl->data;
const union phy_table_tile *end = p + tbl->size / 2;
- struct rtw_phy_cond pos_cond = {0};
+ struct rtw_phy_cond pos_cond = {};
+ struct rtw_phy_cond2 pos_cond2 = {};
bool is_matched = true, is_skipped = false;
BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair));
@@ -1109,11 +1161,12 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
case BRANCH_ELIF:
default:
pos_cond = p->cond;
+ pos_cond2 = p->cond2;
break;
}
} else if (p->cond.neg) {
if (!is_skipped) {
- if (check_positive(rtwdev, pos_cond)) {
+ if (check_positive(rtwdev, pos_cond, pos_cond2)) {
is_matched = true;
is_skipped = true;
} else {
@@ -1470,10 +1523,8 @@ static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev,
rate = rates[i];
if (band == PHY_BAND_2G)
hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset;
- else if (band == PHY_BAND_5G)
- hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
else
- continue;
+ hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
}
}
@@ -2125,8 +2176,8 @@ void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw,
*limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path,
rate, ch, regd);
- *remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
- dm_info->txagc_remnant_ofdm);
+ *remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
+ dm_info->txagc_remnant_ofdm[path];
*sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate);
}
@@ -2340,7 +2391,8 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev)
void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
struct rtw_swing_table *swing_table)
{
- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
+ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
+ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
u8 channel = rtwdev->hal.current_channel;
if (IS_CH_2G_BAND(channel)) {
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index 4d9b8668e8b0..e4d506cf9c33 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -9,6 +9,7 @@
#define BIT_FEN_EN_25_1 BIT(13)
#define BIT_FEN_ELDR BIT(12)
#define BIT_FEN_CPUEN BIT(2)
+#define BIT_FEN_USBA BIT(2)
#define BIT_FEN_BB_GLB_RST BIT(1)
#define BIT_FEN_BB_RSTB BIT(0)
#define BIT_R_DIS_PRST BIT(6)
@@ -16,6 +17,10 @@
#define REG_SYS_PW_CTRL 0x0004
#define BIT_PFM_WOWL BIT(3)
#define BIT_APFM_OFFMAC BIT(9)
+#define REG_APS_FSMCO 0x0004
+#define APS_FSMCO_MAC_ENABLE BIT(8)
+#define APS_FSMCO_MAC_OFF BIT(9)
+#define APS_FSMCO_HW_POWERDOWN BIT(15)
#define REG_SYS_CLK_CTRL 0x0008
#define BIT_CPU_CLK_EN BIT(14)
@@ -58,6 +63,8 @@
#define BIT_SHIFT_LDO25_VOLTAGE 4
#define BIT_LDO25_EN BIT(7)
+#define REG_ACLK_MON 0x3e
+
#define REG_GPIO_MUXCFG 0x0040
#define BIT_FSPI_EN BIT(19)
#define BIT_EN_SIC BIT(12)
@@ -90,6 +97,8 @@
#define BIT_USB_SUS_DIS BIT(8)
#define BIT_SDIO_PAD_E5 BIT(18)
+#define REG_RF_B_CTRL 0x76
+
#define REG_AFE_CTRL_4 0x0078
#define BIT_CK320M_AFE_EN BIT(4)
#define BIT_EN_SYN BIT(15)
@@ -134,6 +143,11 @@
#define REG_PMC_DBG_CTRL1 0xa8
#define BITS_PMC_BT_IQK_STS GENMASK(22, 21)
+#define REG_HIMR0 0xb0
+#define REG_HISR0 0xb4
+#define REG_HIMR1 0xb8
+#define REG_HISR1 0xbc
+
#define REG_PAD_CTRL2 0x00C4
#define BIT_RSM_EN_V1 BIT(16)
#define BIT_NO_PDN_CHIPOFF_V1 BIT(17)
@@ -185,6 +199,15 @@
#define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \
BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \
BIT_MACTXEN | BIT_MACRXEN)
+#define REG_PBP 0x104
+#define PBP_RX_MASK 0x0f
+#define PBP_TX_MASK 0xf0
+#define PBP_64 0x0
+#define PBP_128 0x1
+#define PBP_256 0x2
+#define PBP_512 0x3
+#define PBP_1024 0x4
+
#define BIT_SHIFT_TXDMA_VOQ_MAP 4
#define BIT_MASK_TXDMA_VOQ_MAP 0x3
#define BIT_TXDMA_VOQ_MAP(x) \
@@ -256,6 +279,8 @@
#define REG_HMEBOX1 0x01D4
#define REG_HMEBOX2 0x01D8
#define REG_HMEBOX3 0x01DC
+#define REG_LLT_INIT 0x01E0
+#define BIT_LLT_WRITE_ACCESS BIT(30)
#define REG_HMEBOX0_EX 0x01F0
#define REG_HMEBOX1_EX 0x01F4
#define REG_HMEBOX2_EX 0x01F8
@@ -298,6 +323,7 @@
#define REG_AUTO_LLT 0x0224
#define BIT_AUTO_INIT_LLT BIT(16)
+#define REG_DWBCN1_CTRL 0x0228
#define REG_RQPN_CTRL_1 0x0228
#define REG_RQPN_CTRL_2 0x022C
#define BIT_LD_RQPN BIT(31)
@@ -329,6 +355,7 @@
#define BIT_DMA_BURST_SIZE_1024 0
#define REG_RXPKTNUM 0x02B0
+#define REG_EARLY_MODE_CONTROL 0x02BC
#define REG_INT_MIG 0x0304
#define REG_HCI_MIX_CFG 0x03FC
@@ -336,6 +363,7 @@
#define REG_BCNQ_INFO 0x0418
#define BIT_MGQ_CPU_EMPTY BIT(24)
+#define REG_TXPKT_EMPTY 0x041A
#define REG_FWHW_TXQ_CTRL 0x0420
#define BIT_EN_BCNQ_DL BIT(22)
#define BIT_EN_WR_FREE_TAIL BIT(20)
@@ -362,10 +390,12 @@
#define REG_AMPDU_MAX_TIME_V1 0x0455
#define REG_BCNQ1_BDNY_V1 0x0456
#define REG_AMPDU_MAX_TIME 0x0456
+#define REG_AMPDU_MAX_LENGTH 0x0458
#define REG_WMAC_LBK_BF_HD 0x045D
#define REG_TX_HANG_CTRL 0x045E
#define BIT_EN_GNT_BT_AWAKE BIT(3)
#define BIT_EN_EOF_V1 BIT(2)
+#define REG_FAST_EDCA_CTRL 0x0460
#define REG_DATA_SC 0x0483
#define REG_ARFR2_V1 0x048C
#define REG_ARFRH2_V1 0x0490
@@ -390,6 +420,8 @@
#define REG_PRECNT_CTRL 0x04E5
#define BIT_BTCCA_CTRL (BIT(0) | BIT(1))
#define BIT_EN_PRECNT BIT(11)
+#define REG_TX_RPT_CTRL 0x04EC
+#define REG_TX_RPT_TIME 0x04F0
#define REG_DUMMY_PAGE4_V1 0x04FC
#define REG_EDCA_VO_PARAM 0x0500
@@ -400,6 +432,7 @@
#define BIT_MASK_CWMAX GENMASK(15, 12)
#define BIT_MASK_CWMIN GENMASK(11, 8)
#define BIT_MASK_AIFS GENMASK(7, 0)
+#define REG_BCNTCFG 0x0510
#define REG_PIFS 0x0512
#define REG_SIFS 0x0514
#define BIT_SHIFT_SIFS_OFDM_CTX 8
@@ -526,6 +559,8 @@
#define REG_BT_COEX_V2 0x0762
#define BIT_GNT_BT_POLARITY BIT(12)
#define BIT_LTE_COEX_EN BIT(7)
+#define REG_GNT_BT 0x0765
+#define BIT_PTA_SW_CTL GENMASK(4, 3)
#define REG_BT_COEX_ENH_INTR_CTRL 0x76E
#define BIT_R_GRANTALL_WLMASK BIT(3)
#define BIT_STATIS_BT_EN BIT(2)
@@ -543,14 +578,43 @@
#define REG_FPGA0_RFMOD 0x0800
#define BIT_CCKEN BIT(24)
#define BIT_OFDMEN BIT(25)
+#define REG_CCK_RPT_FORMAT 0x0804
+#define BIT_CCK_RPT_FORMAT BIT(16)
+#define REG_RXPSEL 0x0808
+#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
+#define REG_TXPSEL 0x080C
#define REG_RX_GAIN_EN 0x081c
+#define REG_CCASEL 0x082C
+#define REG_PDMFTH 0x0830
+#define REG_BWINDICATION 0x0834
+#define REG_CCA2ND 0x0838
+#define REG_L1PKTH 0x0848
+#define REG_CLKTRK 0x0860
+#define REG_ADCCLK 0x08AC
+#define REG_HSSI_READ 0x08B0
+#define REG_FPGA0_XCD_RF_PARA 0x08B4
+#define REG_RX_MCS_LIMIT 0x08BC
+#define REG_ADC160 0x08C4
+#define REG_ANTSEL_SW 0x0900
+#define REG_DAC_RSTB 0x090c
+#define REG_SINGLE_TONE_CONT_TX 0x0914
#define REG_RFE_CTRL_E 0x0974
#define REG_2ND_CCA_CTRL 0x0976
+#define REG_IQK_COM00 0x0978
+#define REG_IQK_COM32 0x097c
+#define REG_IQK_COM64 0x0980
+#define REG_IQK_COM96 0x0984
+
+#define REG_FAS 0x09a4
+#define REG_RXSB 0x0a00
+#define REG_CCK_RX 0x0a04
+#define REG_CCK_PD_TH 0x0a0a
#define REG_CCK0_FAREPORT 0xa2c
#define BIT_CCK0_2RX BIT(18)
#define BIT_CCK0_MRC BIT(22)
+#define REG_FA_CCK 0x0a5c
#define REG_DIS_DPD 0x0a70
#define DIS_DPD_MASK GENMASK(9, 0)
@@ -566,13 +630,109 @@
#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9)
#define DIS_DPD_RATEALL GENMASK(9, 0)
+#define REG_CNTRST 0x0b58
+
+#define REG_3WIRE_SWA 0x0c00
+#define REG_RX_IQC_AB_A 0x0c10
+#define REG_TXSCALE_A 0x0c1c
+#define BB_SWING_MASK GENMASK(31, 21)
+#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20
+#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24
+#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28
+#define REG_TX_AGC_A_MCS3_MCS0 0xc2c
+#define REG_TX_AGC_A_MCS7_MCS4 0xc30
+#define REG_TX_AGC_A_MCS11_MCS8 0xc34
+#define REG_TX_AGC_A_MCS15_MCS12 0xc38
+#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c
+#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40
+#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44
+#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48
+#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c
+#define REG_RXIGI_A 0x0c50
+#define REG_TX_PWR_TRAINING_A 0x0c54
+#define REG_CK_MONHA 0x0c5c
+#define REG_AFE_PWR1_A 0x0c60
+#define REG_AFE_PWR2_A 0x0c64
+#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68
+#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80
+#define REG_OFDM0_A_TX_AFE 0x0c84
+#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88
+#define REG_TSSI_TRK_SW 0x0c8c
+#define REG_LSSI_WRITE_A 0x0c90
+#define REG_PREDISTA 0x0c90
+#define REG_TXAGCIDX 0x0c94
+
+#define REG_RFE_PINMUX_A 0x0cb0
+#define REG_RFE_INV_A 0x0cb4
#define REG_RFE_CTRL8 0x0cb4
#define BIT_MASK_RFE_SEL89 GENMASK(7, 0)
+#define PTA_CTRL_PIN 0x66
+#define DPDT_CTRL_PIN 0x77
+#define RFE_INV_MASK 0x3ff00000
+#define REG_RFECTL_A 0x0cb8
#define REG_RFE_INV8 0x0cbd
#define BIT_MASK_RFE_INV89 GENMASK(1, 0)
#define REG_RFE_INV16 0x0cbe
#define BIT_RFE_BUF_EN BIT(3)
+#define REG_IQK_DPD_CFG 0x0cc4
+#define REG_CFG_PMPD 0x0cc8
+#define REG_IQC_Y 0x0ccc
+#define REG_IQC_X 0x0cd4
+#define REG_INTPO_SETA 0x0ce8
+
+#define REG_IQKA_END 0x0d00
+#define REG_PI_READ_A 0x0d04
+#define REG_SI_READ_A 0x0d08
+#define REG_IQKB_END 0x0d40
+#define REG_PI_READ_B 0x0d44
+#define REG_SI_READ_B 0x0d48
+
+#define REG_3WIRE_SWB 0x0e00
+#define REG_RX_IQC_AB_B 0x0e10
+#define REG_TXSCALE_B 0x0e1c
+#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20
+#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24
+#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28
+#define REG_TX_AGC_B_MCS3_MCS0 0xe2c
+#define REG_TX_AGC_B_MCS7_MCS4 0xe30
+#define REG_TX_AGC_B_MCS11_MCS8 0xe34
+#define REG_TX_AGC_B_MCS15_MCS12 0xe38
+#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c
+#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40
+#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44
+#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48
+#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c
+#define REG_RXIGI_B 0x0e50
+#define REG_TX_PWR_TRAINING_B 0x0e54
+#define REG_CK_MONHB 0x0e5c
+#define REG_AFE_PWR1_B 0x0e60
+#define REG_AFE_PWR2_B 0x0e64
+#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68
+#define REG_TXTONEB 0x0e80
+#define REG_RXTONEB 0x0e84
+#define REG_TXPITMB 0x0e88
+#define REG_RXPITMB 0x0e8c
+#define REG_LSSI_WRITE_B 0x0e90
+#define REG_PREDISTB 0x0e90
+#define REG_INIDLYB 0x0e94
+#define REG_RFE_PINMUX_B 0x0eb0
+#define REG_RFE_INV_B 0x0eb4
+#define REG_RFECTL_B 0x0eb8
+#define REG_BPBDB 0x0ec4
+#define REG_PHYTXONB 0x0ec8
+#define REG_IQKYB 0x0ecc
+#define REG_IQKXB 0x0ed4
+#define REG_INTPO_SETB 0x0ee8
+
+#define REG_CRC_CCK 0x0f04
+#define REG_CCA_OFDM 0x0f08
+#define REG_CRC_VHT 0x0f0c
+#define REG_CRC_HT 0x0f10
+#define REG_CRC_OFDM 0x0f14
+#define REG_FA_OFDM 0x0f48
+#define REG_CCA_CCK 0x0fcc
+
#define REG_ANAPARSW_MAC_0 0x1010
#define BIT_CF_L_V2 GENMASK(29, 28)
@@ -709,6 +869,10 @@
#define REG_IGN_GNTBT4 0x4160
+#define REG_USB_MOD 0xf008
+#define REG_USB3_RXITV 0xf050
+#define REG_USB_HRPWM 0xfe58
+
#define RF_MODE 0x00
#define RF_MODOPT 0x01
#define RF_WLINT 0x01
@@ -716,7 +880,13 @@
#define RF_DTXLOK 0x08
#define RF_CFGCH 0x18
#define BIT_BAND GENMASK(18, 16)
+#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8))
+#define RF18_CHANNEL_MASK (MASKBYTE0)
+#define RF18_RFSI_MASK (BIT(18) | BIT(17))
#define RF_RCK 0x1d
+#define RF_MODE_TABLE_ADDR 0x30
+#define RF_MODE_TABLE_DATA0 0x31
+#define RF_MODE_TABLE_DATA1 0x32
#define RF_LUTWA 0x33
#define RF_LUTWD1 0x3e
#define RF_LUTWD0 0x3f
@@ -725,10 +895,14 @@
#define RF_T_METER 0x42
#define RF_BSPAD 0x54
#define RF_GAINTX 0x56
+#define RF_TXMOD 0x58
#define RF_TXATANK 0x64
+#define RF_TXA_PREPAD 0x65
#define RF_TRXIQ 0x66
#define RF_RXIQGEN 0x8d
+#define RF_RXBB2 0x8f
#define RF_SYN_PFD 0xb0
+#define RF_LCK 0xb4
#define RF_XTALX2 0xb8
#define RF_SYN_CTRL 0xbb
#define RF_MALSEL 0xbe
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index 77399b8dd8cd..a19b94d022ee 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -493,11 +493,6 @@ static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = {
NULL
};
-static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {
- [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl,
- .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,},
-};
-
static const struct rtw_page_table page_table_8703b[] = {
{12, 2, 2, 0, 1},
{12, 2, 2, 0, 1},
@@ -637,7 +632,7 @@ static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev)
dm_info->pwr_trk_init_trigger = true;
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
dm_info->txagc_remnant_cck = 0;
- dm_info->txagc_remnant_ofdm = 0;
+ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0;
}
static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev)
@@ -1589,7 +1584,7 @@ static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- dm_info->txagc_remnant_ofdm = txagc_idx;
+ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx;
/* Only path A is calibrated for rtl8703b */
rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
@@ -1818,6 +1813,12 @@ static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = {
.pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p,
};
+static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {
+ [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl,
+ .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,
+ .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, },
+};
+
/* Shared-Antenna Coex Table */
static const struct coex_table_para table_sant_8703b[] = {
{0xffffffff, 0xffffffff}, /* case-0 */
@@ -1888,6 +1889,8 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
};
static const struct rtw_chip_ops rtw8703b_ops = {
+ .power_on = rtw_power_on,
+ .power_off = rtw_power_off,
.mac_init = rtw8723x_mac_init,
.dump_fw_crash = NULL,
.shutdown = NULL,
@@ -1960,6 +1963,9 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.max_power_index = 0x3f,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */
+ .hw_feature_report = true,
+ .c2h_ra_report_size = 7,
+ .old_datarate_fb_limit = true,
.path_div_supported = false,
.ht_supported = true,
@@ -1992,7 +1998,6 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs),
.iqk_threshold = 8,
- .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl,
/* WOWLAN firmware exists, but not implemented yet */
.wow_fw_name = "rtw88/rtw8703b_wow_fw.bin",
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 86a5e2497641..eeca31bf71f1 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -79,7 +79,7 @@ static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev)
dm_info->pwr_trk_init_trigger = true;
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
dm_info->txagc_remnant_cck = 0;
- dm_info->txagc_remnant_ofdm = 0;
+ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0;
}
static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)
@@ -1265,7 +1265,7 @@ static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- dm_info->txagc_remnant_ofdm = txagc_idx;
+ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx;
rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B);
@@ -1390,6 +1390,8 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
}
static const struct rtw_chip_ops rtw8723d_ops = {
+ .power_on = rtw_power_on,
+ .power_off = rtw_power_off,
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723x_read_efuse,
.query_phy_status = query_phy_status,
@@ -2018,11 +2020,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8723d = {
.n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d),
};
-static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
- [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
- .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,},
-};
-
static const u8 rtw8723d_pwrtrk_2gb_n[] = {
0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5,
6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10
@@ -2086,6 +2083,12 @@ static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = {
.pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n,
};
+static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
+ [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
+ .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,
+ .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, },
+};
+
static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = {
{0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32},
{0x67, BIT(7), RTW_REG_DOMAIN_MAC8},
@@ -2131,6 +2134,9 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x20,
.usb_tx_agg_desc_num = 1,
+ .hw_feature_report = true,
+ .c2h_ra_report_size = 7,
+ .old_datarate_fb_limit = true,
.ht_supported = true,
.vht_supported = false,
.lps_deep_mode_supported = 0,
@@ -2154,7 +2160,6 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.rfe_defs = rtw8723d_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs),
.rx_ldpc = false,
- .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
index 0d0b6c2cb9aa..69f73cb5b4cd 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
@@ -595,7 +595,8 @@ void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
u8 delta)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
+ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
+ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
const s8 *pwrtrk_xtal;
s8 xtal_cap;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
new file mode 100644
index 000000000000..482edd31823d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
@@ -0,0 +1,1102 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "main.h"
+#include "coex.h"
+#include "phy.h"
+#include "reg.h"
+#include "rtw88xxa.h"
+#include "rtw8812a.h"
+#include "rtw8812a_table.h"
+#include "tx.h"
+
+static void rtw8812a_power_off(struct rtw_dev *rtwdev)
+{
+ rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a);
+}
+
+static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx)
+{
+ s8 rx_pwr_all = 0;
+
+ switch (lna_idx) {
+ case 7:
+ if (vga_idx <= 27)
+ rx_pwr_all = -94 + 2 * (27 - vga_idx);
+ else
+ rx_pwr_all = -94;
+ break;
+ case 6:
+ rx_pwr_all = -42 + 2 * (2 - vga_idx);
+ break;
+ case 5:
+ rx_pwr_all = -36 + 2 * (7 - vga_idx);
+ break;
+ case 4:
+ rx_pwr_all = -30 + 2 * (7 - vga_idx);
+ break;
+ case 3:
+ rx_pwr_all = -18 + 2 * (7 - vga_idx);
+ break;
+ case 2:
+ rx_pwr_all = 2 * (5 - vga_idx);
+ break;
+ case 1:
+ rx_pwr_all = 14 - 2 * vga_idx;
+ break;
+ case 0:
+ rx_pwr_all = 20 - 2 * vga_idx;
+ break;
+ default:
+ break;
+ }
+
+ return rx_pwr_all;
+}
+
+static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat,
+ rtw8812a_cck_rx_pwr);
+
+ if (pkt_stat->rate >= DESC_RATE6M)
+ return;
+
+ if (rtwdev->hal.cck_high_power)
+ return;
+
+ if (pkt_stat->rssi >= 80)
+ pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) +
+ ((pkt_stat->rssi - 80) >> 1) + 80;
+ else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20)
+ pkt_stat->rssi += 3;
+}
+
+static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
+{
+}
+
+static void rtw8812a_do_lck(struct rtw_dev *rtwdev)
+{
+ u32 cont_tx, lc_cal, i;
+
+ cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000);
+
+ lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
+
+ if (!cont_tx)
+ rtw_write8(rtwdev, REG_TXPAUSE, 0xff);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1);
+
+ mdelay(150);
+
+ for (i = 0; i < 5; i++) {
+ if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1)
+ break;
+
+ mdelay(10);
+ }
+
+ if (i == 5)
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n");
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0);
+
+ if (!cont_tx)
+ rtw_write8(rtwdev, REG_TXPAUSE, 0);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
+}
+
+static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup,
+ u32 *rfb_backup, const u32 *backup_rf_reg,
+ u32 rf_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* Save RF Parameters */
+ for (i = 0; i < rf_num; i++) {
+ rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A,
+ backup_rf_reg[i], MASKDWORD);
+ rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B,
+ backup_rf_reg[i], MASKDWORD);
+ }
+}
+
+static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev,
+ enum rtw_rf_path path,
+ const u32 *backup_rf_reg,
+ u32 *RF_backup, u32 rf_reg_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ for (i = 0; i < rf_reg_num; i++)
+ rtw_write_rf(rtwdev, path, backup_rf_reg[i],
+ RFREG_MASK, RF_backup[i]);
+
+ rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0);
+}
+
+static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
+ const u32 *backup_afe_reg, u32 afe_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* Reload AFE Parameters */
+ for (i = 0; i < afe_num; i++)
+ rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0);
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0);
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0);
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);
+ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1);
+ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1);
+ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1);
+ rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1);
+
+ rtw_write32(rtwdev, REG_TXTONEB, 0x0);
+ rtw_write32(rtwdev, REG_RXTONEB, 0x0);
+ rtw_write32(rtwdev, REG_TXPITMB, 0x0);
+ rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000);
+ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1);
+ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1);
+ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1);
+ rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1);
+}
+
+static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,
+ unsigned int rx_x, unsigned int rx_y)
+{
+ switch (path) {
+ case RF_PATH_A:
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ if (rx_x >> 1 >= 0x112 ||
+ (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x000003ff, 0x100);
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x03ff0000, 0);
+ } else {
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x000003ff, rx_x >> 1);
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x03ff0000, rx_y >> 1);
+ }
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
+ rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n",
+ rtw_read32(rtwdev, REG_RX_IQC_AB_A));
+ break;
+ case RF_PATH_B:
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ if (rx_x >> 1 >= 0x112 ||
+ (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
+ 0x000003ff, 0x100);
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
+ 0x03ff0000, 0);
+ } else {
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
+ 0x000003ff, rx_x >> 1);
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
+ 0x03ff0000, rx_y >> 1);
+ }
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
+ rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n",
+ rtw_read32(rtwdev, REG_RX_IQC_AB_B));
+ break;
+ default:
+ break;
+ }
+}
+
+static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,
+ unsigned int tx_x, unsigned int tx_y)
+{
+ switch (path) {
+ case RF_PATH_A:
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1);
+ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1);
+ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y);
+ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx_x = %x;;tx_y = %x =====> fill to IQC\n",
+ tx_x & 0x000007ff, tx_y & 0x000007ff);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
+ rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff),
+ rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff));
+ break;
+ case RF_PATH_B:
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1);
+ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1);
+ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y);
+ rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx_x = %x;;tx_y = %x =====> fill to IQC\n",
+ tx_x & 0x000007ff, tx_y & 0x000007ff);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "0xed4 = %x;;0xecc = %x ====>fill to IQC\n",
+ rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff),
+ rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff));
+ break;
+ default:
+ break;
+ }
+}
+
+static void rtw8812a_iqk(struct rtw_dev *rtwdev)
+{
+ int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10];
+ int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10];
+ bool iqk0_ready = false, tx0_finish = false, rx0_finish = false;
+ bool iqk1_ready = false, tx1_finish = false, rx1_finish = false;
+ u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0;
+ int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0;
+ int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ bool tx0_fail = true, rx0_fail = true;
+ bool tx1_fail = true, rx1_fail = true;
+ u8 cal0_retry, cal1_retry;
+ u8 delay_count;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* ========path-A AFE all on======== */
+ /* Port 0 DAC/ADC on */
+ rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777);
+ rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777);
+
+ /* Port 1 DAC/ADC on */
+ rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777);
+ rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777);
+
+ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979);
+ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979);
+
+ /* hardware 3-wire off */
+ rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4);
+ rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4);
+
+ /* DAC/ADC sampling rate (160 MHz) */
+ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7);
+ rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7);
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ /* ====== path A TX IQK RF setting ====== */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);
+
+ /* ====== path B TX IQK RF setting ====== */
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001);
+
+ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
+ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);
+ rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1);
+ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */
+ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */
+ rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ if (efuse->ext_pa_5g) {
+ if (efuse->rfe_option == 1) {
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3);
+ rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3);
+ } else {
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7);
+ rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7);
+ }
+ } else {
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1);
+ rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1);
+ }
+
+ if (rtwdev->hal.current_band_type == RTW_BAND_5G) {
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96);
+ rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96);
+ } else {
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96);
+ rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96);
+
+ if (efuse->rfe_option == 3) {
+ if (efuse->ext_pa_2g)
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ 0x821403e3);
+ else
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ 0x821403f7);
+ }
+ }
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);
+ rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000);
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10);
+ rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000);
+
+ cal0_retry = 0;
+ cal1_retry = 0;
+ while (1) {
+ /* one shot */
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
+
+ mdelay(10);
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
+
+ for (delay_count = 0; delay_count < 20; delay_count++) {
+ if (!tx0_finish)
+ iqk0_ready = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ BIT(10));
+ if (!tx1_finish)
+ iqk1_ready = rtw_read32_mask(rtwdev,
+ REG_IQKB_END,
+ BIT(10));
+ if (iqk0_ready && iqk1_ready)
+ break;
+
+ mdelay(1);
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n",
+ delay_count);
+
+ if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
+ /* ============TXIQK Check============== */
+ tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12));
+ tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12));
+
+ if (!(tx0_fail || tx0_finish)) {
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);
+ tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
+ tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ 0x07ff0000);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n",
+ tx0_avg, tx_x0_temp[tx0_avg],
+ tx0_avg, tx_y0_temp[tx0_avg]);
+
+ tx_x0_temp[tx0_avg] <<= 21;
+ tx_y0_temp[tx0_avg] <<= 21;
+
+ tx0_avg++;
+ } else {
+ cal0_retry++;
+ if (cal0_retry == 10)
+ break;
+ }
+
+ if (!(tx1_fail || tx1_finish)) {
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000);
+ tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKB_END,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000);
+ tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKB_END,
+ 0x07ff0000);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n",
+ tx1_avg, tx_x1_temp[tx1_avg],
+ tx1_avg, tx_y1_temp[tx1_avg]);
+
+ tx_x1_temp[tx1_avg] <<= 21;
+ tx_y1_temp[tx1_avg] <<= 21;
+
+ tx1_avg++;
+ } else {
+ cal1_retry++;
+ if (cal1_retry == 10)
+ break;
+ }
+ } else {
+ cal0_retry++;
+ cal1_retry++;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "delay 20ms TX IQK Not Ready!!!!!\n");
+
+ if (cal0_retry == 10)
+ break;
+ }
+
+ if (tx0_avg >= 2)
+ tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4,
+ tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0,
+ false, false);
+
+ if (tx1_avg >= 2)
+ tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4,
+ tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1,
+ false, false);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx0_average = %d, tx1_average = %d\n",
+ tx0_avg, tx1_avg);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx0_finish = %d, tx1_finish = %d\n",
+ tx0_finish, tx1_finish);
+
+ if (tx0_finish && tx1_finish)
+ break;
+
+ if ((cal0_retry + tx0_avg) >= 10 ||
+ (cal1_retry + tx1_avg) >= 10)
+ break;
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry);
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ /* Load LOK */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00,
+ rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00));
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00,
+ rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00));
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ if (tx0_finish) {
+ /* ====== path A RX IQK RF setting====== */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
+ 0x30000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
+ 0x3f7ff);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
+ 0xfe7bf);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
+ }
+ if (tx1_finish) {
+ /* ====== path B RX IQK RF setting====== */
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK,
+ 0x30000);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK,
+ 0x3f7ff);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK,
+ 0xfe7bf);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000);
+ }
+
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0);
+ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
+
+ if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
+ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911);
+ else
+ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890);
+
+ if (efuse->rfe_option == 1) {
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717);
+ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717);
+ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);
+ } else {
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717);
+ rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717);
+ rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077);
+ }
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ if (tx0_finish) {
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10);
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119);
+ }
+ if (tx1_finish) {
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10);
+ rtw_write32(rtwdev, REG_TXPITMB, 0x82140119);
+ }
+
+ cal0_retry = 0;
+ cal1_retry = 0;
+ while (1) {
+ /* one shot */
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ if (tx0_finish) {
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,
+ tx_x0 & 0x000007ff);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,
+ tx_y0 & 0x000007ff);
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+ if (efuse->rfe_option == 1)
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500);
+ else
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+ mdelay(5);
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+ }
+
+ if (tx1_finish) {
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,
+ tx_x1 & 0x000007ff);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,
+ tx_y1 & 0x000007ff);
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+ if (efuse->rfe_option == 1)
+ rtw_write32(rtwdev, REG_RXPITMB, 0x28161500);
+ else
+ rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);
+ mdelay(5);
+ rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
+ }
+
+ for (delay_count = 0; delay_count < 20; delay_count++) {
+ if (!rx0_finish && tx0_finish)
+ iqk0_ready = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ BIT(10));
+ if (!rx1_finish && tx1_finish)
+ iqk1_ready = rtw_read32_mask(rtwdev,
+ REG_IQKB_END,
+ BIT(10));
+ if (iqk0_ready && iqk1_ready)
+ break;
+
+ mdelay(1);
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n",
+ delay_count);
+
+ if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
+ /* ============RXIQK Check============== */
+ rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11));
+ rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11));
+
+ if (!(rx0_fail || rx0_finish) && tx0_finish) {
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
+ rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
+ rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ 0x07ff0000);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n",
+ rx0_avg, rx_x0_temp[rx0_avg],
+ rx0_avg, rx_y0_temp[rx0_avg]);
+
+ rx_x0_temp[rx0_avg] <<= 21;
+ rx_y0_temp[rx0_avg] <<= 21;
+
+ rx0_avg++;
+ } else {
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "1. RXA_cal_retry = %d\n", cal0_retry);
+
+ cal0_retry++;
+ if (cal0_retry == 10)
+ break;
+ }
+
+ if (!(rx1_fail || rx1_finish) && tx1_finish) {
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000);
+ rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKB_END,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000);
+ rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev,
+ REG_IQKB_END,
+ 0x07ff0000);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n",
+ rx1_avg, rx_x1_temp[rx1_avg],
+ rx1_avg, rx_y1_temp[rx1_avg]);
+
+ rx_x1_temp[rx1_avg] <<= 21;
+ rx_y1_temp[rx1_avg] <<= 21;
+
+ rx1_avg++;
+ } else {
+ cal1_retry++;
+ if (cal1_retry == 10)
+ break;
+ }
+ } else {
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "2. RXA_cal_retry = %d\n", cal0_retry);
+
+ cal0_retry++;
+ cal1_retry++;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "delay 20ms RX IQK Not Ready!!!!!\n");
+
+ if (cal0_retry == 10)
+ break;
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n",
+ cal0_retry);
+
+ if (rx0_avg >= 2)
+ rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4,
+ rx_x0_temp, rx_y0_temp,
+ &rx_x0, &rx_y0,
+ true, false);
+
+ if (rx1_avg >= 2)
+ rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4,
+ rx_x1_temp, rx_y1_temp,
+ &rx_x1, &rx_y1,
+ true, false);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx0_average = %d, rx1_average = %d\n",
+ rx0_avg, rx1_avg);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx0_finish = %d, rx1_finish = %d\n",
+ rx0_finish, rx1_finish);
+
+ if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish))
+ break;
+
+ if ((cal0_retry + rx0_avg) >= 10 ||
+ (cal1_retry + rx1_avg) >= 10 ||
+ rx0_avg == 3 || rx1_avg == 3)
+ break;
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry);
+
+ /* FillIQK Result */
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n");
+
+ if (tx0_finish)
+ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0);
+ else
+ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0);
+
+ if (rx0_finish)
+ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0);
+ else
+ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n");
+
+ if (tx1_finish)
+ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1);
+ else
+ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0);
+
+ if (rx1_finish)
+ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1);
+ else
+ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0);
+}
+
+#define MACBB_REG_NUM_8812A 9
+#define AFE_REG_NUM_8812A 12
+#define RF_REG_NUM_8812A 3
+
+static void rtw8812a_do_iqk(struct rtw_dev *rtwdev)
+{
+ static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = {
+ 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c
+ };
+ static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = {
+ 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4,
+ 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4
+ };
+ static const u32 backup_rf_reg[RF_REG_NUM_8812A] = {
+ 0x65, 0x8f, 0x0
+ };
+ u32 macbb_backup[MACBB_REG_NUM_8812A] = {};
+ u32 afe_backup[AFE_REG_NUM_8812A] = {};
+ u32 rfa_backup[RF_REG_NUM_8812A] = {};
+ u32 rfb_backup[RF_REG_NUM_8812A] = {};
+ u32 reg_cb8, reg_eb8;
+
+ rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8812A);
+
+ rtw_write32_set(rtwdev, REG_CCASEL, BIT(31));
+ reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A);
+ reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B);
+ rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31));
+
+ rtw88xxa_iqk_backup_afe(rtwdev, afe_backup,
+ backup_afe_reg, AFE_REG_NUM_8812A);
+ rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup,
+ backup_rf_reg, RF_REG_NUM_8812A);
+
+ rtw88xxa_iqk_configure_mac(rtwdev);
+
+ rtw8812a_iqk(rtwdev);
+
+ rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg,
+ rfa_backup, RF_REG_NUM_8812A);
+ rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg,
+ rfb_backup, RF_REG_NUM_8812A);
+
+ rtw8812a_iqk_restore_afe(rtwdev, afe_backup,
+ backup_afe_reg, AFE_REG_NUM_8812A);
+
+ rtw_write32_set(rtwdev, REG_CCASEL, BIT(31));
+ rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8);
+ rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8);
+ rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31));
+
+ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8812A);
+}
+
+static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev)
+{
+ u8 channel = rtwdev->hal.current_channel;
+
+ rtw8812a_do_iqk(rtwdev);
+
+ /* The official driver wants to do this after connecting
+ * but before first writing a new igi (phydm_get_new_igi).
+ * Here seems close enough.
+ */
+ if (channel >= 36 && channel <= 64)
+ rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl);
+ else if (channel >= 100)
+ rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl);
+}
+
+static void rtw8812a_pwr_track(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ if (!dm_info->pwr_trk_triggered) {
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
+ GENMASK(17, 16), 0x03);
+ dm_info->pwr_trk_triggered = true;
+ return;
+ }
+
+ rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk);
+ dm_info->pwr_trk_triggered = false;
+}
+
+static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ u8 *txdesc)
+{
+ fill_txdesc_checksum_common(txdesc, 16);
+}
+
+static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
+{
+}
+
+static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
+{
+}
+
+static const struct rtw_chip_ops rtw8812a_ops = {
+ .power_on = rtw88xxa_power_on,
+ .power_off = rtw8812a_power_off,
+ .phy_set_param = NULL,
+ .read_efuse = rtw88xxa_read_efuse,
+ .query_phy_status = rtw8812a_query_phy_status,
+ .set_channel = rtw88xxa_set_channel,
+ .mac_init = NULL,
+ .read_rf = rtw88xxa_phy_read_rf,
+ .write_rf = rtw_phy_write_rf_reg_sipi,
+ .set_antenna = NULL,
+ .set_tx_power_index = rtw88xxa_set_tx_power_index,
+ .cfg_ldo25 = rtw8812a_cfg_ldo25,
+ .efuse_grant = rtw88xxa_efuse_grant,
+ .false_alarm_statistics = rtw88xxa_false_alarm_statistics,
+ .phy_calibration = rtw8812a_phy_calibration,
+ .cck_pd_set = rtw88xxa_phy_cck_pd_set,
+ .pwr_track = rtw8812a_pwr_track,
+ .config_bfee = NULL,
+ .set_gid_table = NULL,
+ .cfg_csi_rate = NULL,
+ .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum,
+ .coex_set_init = rtw8812a_coex_cfg_init,
+ .coex_set_ant_switch = NULL,
+ .coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix,
+ .coex_set_gnt_debug = NULL,
+ .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type,
+ .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power,
+ .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,
+};
+
+static const struct rtw_page_table page_table_8812a[] = {
+ /* hq_num, nq_num, lq_num, exq_num, gapq_num */
+ {0, 0, 0, 0, 0}, /* SDIO */
+ {0, 0, 0, 0, 0}, /* PCI */
+ {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */
+ {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */
+ {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */
+};
+
+static const struct rtw_rqpn rqpn_table_8812a[] = {
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH,
+ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+};
+
+static const struct rtw_prioq_addrs prioq_addrs_8812a = {
+ .prio[RTW_DMA_MAPPING_EXTRA] = {
+ .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
+ },
+ .prio[RTW_DMA_MAPPING_LOW] = {
+ .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
+ },
+ .prio[RTW_DMA_MAPPING_NORMAL] = {
+ .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
+ },
+ .prio[RTW_DMA_MAPPING_HIGH] = {
+ .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
+ },
+ .wsize = false,
+};
+
+static const struct rtw_hw_reg rtw8812a_dig[] = {
+ [0] = { .addr = REG_RXIGI_A, .mask = 0x7f },
+ [1] = { .addr = REG_RXIGI_B, .mask = 0x7f },
+};
+
+static const struct rtw_rfe_def rtw8812a_rfe_defs[] = {
+ [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl,
+ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,
+ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, },
+ [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl,
+ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,
+ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, },
+ [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl,
+ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,
+ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, },
+};
+
+static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40};
+static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101};
+
+static const struct coex_rf_para rf_para_tx_8812a[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 20, false, 7}, /* for WL-CPT */
+ {8, 17, true, 4},
+ {7, 18, true, 4},
+ {6, 19, true, 4},
+ {5, 20, true, 4}
+};
+
+static const struct coex_rf_para rf_para_rx_8812a[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 20, false, 7}, /* for WL-CPT */
+ {3, 24, true, 5},
+ {2, 26, true, 5},
+ {1, 27, true, 5},
+ {0, 28, true, 5}
+};
+
+static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a));
+
+const struct rtw_chip_info rtw8812a_hw_spec = {
+ .ops = &rtw8812a_ops,
+ .id = RTW_CHIP_TYPE_8812A,
+ .fw_name = "rtw88/rtw8812a_fw.bin",
+ .wlan_cpu = RTW_WCPU_11N,
+ .tx_pkt_desc_sz = 40,
+ .tx_buf_desc_sz = 16,
+ .rx_pkt_desc_sz = 24,
+ .rx_buf_desc_sz = 8,
+ .phy_efuse_size = 512,
+ .log_efuse_size = 512,
+ .ptct_efuse_size = 96 + 1, /* TODO or just 18? */
+ .txff_size = 131072,
+ .rxff_size = 16128,
+ .rsvd_drv_pg_num = 9,
+ .txgi_factor = 1,
+ .is_pwr_by_rate_dec = true,
+ .max_power_index = 0x3f,
+ .csi_buf_pg_num = 0,
+ .band = RTW_BAND_2G | RTW_BAND_5G,
+ .page_size = 512,
+ .dig_min = 0x20,
+ .ht_supported = true,
+ .vht_supported = true,
+ .lps_deep_mode_supported = 0,
+ .sys_func_en = 0xFD,
+ .pwr_on_seq = card_enable_flow_8812a,
+ .pwr_off_seq = card_disable_flow_8812a,
+ .page_table = page_table_8812a,
+ .rqpn_table = rqpn_table_8812a,
+ .prioq_addrs = &prioq_addrs_8812a,
+ .intf_table = NULL,
+ .dig = rtw8812a_dig,
+ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B},
+ .ltecoex_addr = NULL,
+ .mac_tbl = &rtw8812a_mac_tbl,
+ .agc_tbl = &rtw8812a_agc_tbl,
+ .bb_tbl = &rtw8812a_bb_tbl,
+ .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl},
+ .rfe_defs = rtw8812a_rfe_defs,
+ .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs),
+ .rx_ldpc = false,
+ .hw_feature_report = false,
+ .c2h_ra_report_size = 4,
+ .old_datarate_fb_limit = true,
+ .usb_tx_agg_desc_num = 1,
+ .iqk_threshold = 8,
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
+
+ .coex_para_ver = 0, /* no coex code in 8812au driver */
+ .bt_desired_ver = 0,
+ .scbd_support = false,
+ .new_scbd10_def = false,
+ .ble_hid_profile_support = false,
+ .wl_mimo_ps_support = false,
+ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
+ .bt_rssi_type = COEX_BTRSSI_RATIO,
+ .ant_isolation = 15,
+ .rssi_tolerance = 2,
+ .wl_rssi_step = wl_rssi_step_8812a,
+ .bt_rssi_step = bt_rssi_step_8812a,
+ .table_sant_num = 0,
+ .table_sant = NULL,
+ .table_nsant_num = 0,
+ .table_nsant = NULL,
+ .tdma_sant_num = 0,
+ .tdma_sant = NULL,
+ .tdma_nsant_num = 0,
+ .tdma_nsant = NULL,
+ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a),
+ .wl_rf_para_tx = rf_para_tx_8812a,
+ .wl_rf_para_rx = rf_para_rx_8812a,
+ .bt_afh_span_bw20 = 0x20,
+ .bt_afh_span_bw40 = 0x30,
+ .afh_5g_num = 0,
+ .afh_5g = NULL,
+ .coex_info_hw_regs_num = 0,
+ .coex_info_hw_regs = NULL,
+};
+EXPORT_SYMBOL(rtw8812a_hw_spec);
+
+MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.h b/drivers/net/wireless/realtek/rtw88/rtw8812a.h
new file mode 100644
index 000000000000..82dab59e341d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW8812A_H__
+#define __RTW8812A_H__
+
+extern const struct rtw_chip_info rtw8812a_hw_spec;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c
new file mode 100644
index 000000000000..048efbbd49ed
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c
@@ -0,0 +1,2812 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "main.h"
+#include "phy.h"
+#include "rtw8812a_table.h"
+
+static const u32 rtw8812a_mac[] = {
+ 0x010, 0x0000000C,
+ 0x80000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x011, 0x00000066,
+ 0xA0000000, 0x00000000,
+ 0x011, 0x0000005A,
+ 0xB0000000, 0x00000000,
+ 0x025, 0x0000000F,
+ 0x072, 0x00000000,
+ 0x420, 0x00000080,
+ 0x428, 0x0000000A,
+ 0x429, 0x00000010,
+ 0x430, 0x00000000,
+ 0x431, 0x00000000,
+ 0x432, 0x00000000,
+ 0x433, 0x00000001,
+ 0x434, 0x00000002,
+ 0x435, 0x00000003,
+ 0x436, 0x00000005,
+ 0x437, 0x00000007,
+ 0x438, 0x00000000,
+ 0x439, 0x00000000,
+ 0x43A, 0x00000000,
+ 0x43B, 0x00000001,
+ 0x43C, 0x00000002,
+ 0x43D, 0x00000003,
+ 0x43E, 0x00000005,
+ 0x43F, 0x00000007,
+ 0x440, 0x0000005D,
+ 0x441, 0x00000001,
+ 0x442, 0x00000000,
+ 0x444, 0x00000010,
+ 0x445, 0x00000000,
+ 0x446, 0x00000000,
+ 0x447, 0x00000000,
+ 0x448, 0x00000000,
+ 0x449, 0x000000F0,
+ 0x44A, 0x0000000F,
+ 0x44B, 0x0000003E,
+ 0x44C, 0x00000010,
+ 0x44D, 0x00000000,
+ 0x44E, 0x00000000,
+ 0x44F, 0x00000000,
+ 0x450, 0x00000000,
+ 0x451, 0x000000F0,
+ 0x452, 0x0000000F,
+ 0x453, 0x00000000,
+ 0x45B, 0x00000080,
+ 0x460, 0x00000066,
+ 0x461, 0x00000066,
+ 0x4C8, 0x000000FF,
+ 0x4C9, 0x00000008,
+ 0x4CC, 0x000000FF,
+ 0x4CD, 0x000000FF,
+ 0x4CE, 0x00000001,
+ 0x500, 0x00000026,
+ 0x501, 0x000000A2,
+ 0x502, 0x0000002F,
+ 0x503, 0x00000000,
+ 0x504, 0x00000028,
+ 0x505, 0x000000A3,
+ 0x506, 0x0000005E,
+ 0x507, 0x00000000,
+ 0x508, 0x0000002B,
+ 0x509, 0x000000A4,
+ 0x50A, 0x0000005E,
+ 0x50B, 0x00000000,
+ 0x50C, 0x0000004F,
+ 0x50D, 0x000000A4,
+ 0x50E, 0x00000000,
+ 0x50F, 0x00000000,
+ 0x512, 0x0000001C,
+ 0x514, 0x0000000A,
+ 0x516, 0x0000000A,
+ 0x525, 0x0000004F,
+ 0x550, 0x00000010,
+ 0x551, 0x00000010,
+ 0x559, 0x00000002,
+ 0x55C, 0x00000050,
+ 0x55D, 0x000000FF,
+ 0x604, 0x00000009,
+ 0x605, 0x00000030,
+ 0x607, 0x00000003,
+ 0x608, 0x0000000E,
+ 0x609, 0x0000002A,
+ 0x620, 0x000000FF,
+ 0x621, 0x000000FF,
+ 0x622, 0x000000FF,
+ 0x623, 0x000000FF,
+ 0x624, 0x000000FF,
+ 0x625, 0x000000FF,
+ 0x626, 0x000000FF,
+ 0x627, 0x000000FF,
+ 0x638, 0x00000050,
+ 0x63C, 0x0000000A,
+ 0x63D, 0x0000000A,
+ 0x63E, 0x0000000E,
+ 0x63F, 0x0000000E,
+ 0x640, 0x00000080,
+ 0x642, 0x00000040,
+ 0x643, 0x00000000,
+ 0x652, 0x000000C8,
+ 0x66E, 0x00000005,
+ 0x700, 0x00000021,
+ 0x701, 0x00000043,
+ 0x702, 0x00000065,
+ 0x703, 0x00000087,
+ 0x708, 0x00000021,
+ 0x709, 0x00000043,
+ 0x70A, 0x00000065,
+ 0x70B, 0x00000087,
+ 0x718, 0x00000040,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8812a_mac, rtw_phy_cfg_mac);
+
+static const u32 rtw8812a_agc[] = {
+ 0x80000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFC000001,
+ 0x81C, 0xFB020001,
+ 0x81C, 0xFA040001,
+ 0x81C, 0xF9060001,
+ 0x81C, 0xF8080001,
+ 0x81C, 0xF70A0001,
+ 0x81C, 0xF60C0001,
+ 0x81C, 0xF50E0001,
+ 0x81C, 0xF4100001,
+ 0x81C, 0xF3120001,
+ 0x81C, 0xF2140001,
+ 0x81C, 0xF1160001,
+ 0x81C, 0xF0180001,
+ 0x81C, 0xEF1A0001,
+ 0x81C, 0xEE1C0001,
+ 0x81C, 0xED1E0001,
+ 0x81C, 0xEC200001,
+ 0x81C, 0xEB220001,
+ 0x81C, 0xEA240001,
+ 0x81C, 0xCD260001,
+ 0x81C, 0xCC280001,
+ 0x81C, 0xCB2A0001,
+ 0x81C, 0xCA2C0001,
+ 0x81C, 0xC92E0001,
+ 0x81C, 0xC8300001,
+ 0x81C, 0xA6320001,
+ 0x81C, 0xA5340001,
+ 0x81C, 0xA4360001,
+ 0x81C, 0xA3380001,
+ 0x81C, 0xA23A0001,
+ 0x81C, 0x883C0001,
+ 0x81C, 0x873E0001,
+ 0x81C, 0x86400001,
+ 0x81C, 0x85420001,
+ 0x81C, 0x84440001,
+ 0x81C, 0x83460001,
+ 0x81C, 0x82480001,
+ 0x81C, 0x814A0001,
+ 0x81C, 0x484C0001,
+ 0x81C, 0x474E0001,
+ 0x81C, 0x46500001,
+ 0x81C, 0x45520001,
+ 0x81C, 0x44540001,
+ 0x81C, 0x43560001,
+ 0x81C, 0x42580001,
+ 0x81C, 0x415A0001,
+ 0x81C, 0x255C0001,
+ 0x81C, 0x245E0001,
+ 0x81C, 0x23600001,
+ 0x81C, 0x22620001,
+ 0x81C, 0x21640001,
+ 0x81C, 0x21660001,
+ 0x81C, 0x21680001,
+ 0x81C, 0x216A0001,
+ 0x81C, 0x216C0001,
+ 0x81C, 0x216E0001,
+ 0x81C, 0x21700001,
+ 0x81C, 0x21720001,
+ 0x81C, 0x21740001,
+ 0x81C, 0x21760001,
+ 0x81C, 0x21780001,
+ 0x81C, 0x217A0001,
+ 0x81C, 0x217C0001,
+ 0x81C, 0x217E0001,
+ 0x90000001, 0x00000005, 0x40000000, 0x00000000,
+ 0x81C, 0xF9000001,
+ 0x81C, 0xF8020001,
+ 0x81C, 0xF7040001,
+ 0x81C, 0xF6060001,
+ 0x81C, 0xF5080001,
+ 0x81C, 0xF40A0001,
+ 0x81C, 0xF30C0001,
+ 0x81C, 0xF20E0001,
+ 0x81C, 0xF1100001,
+ 0x81C, 0xF0120001,
+ 0x81C, 0xEF140001,
+ 0x81C, 0xEE160001,
+ 0x81C, 0xED180001,
+ 0x81C, 0xEC1A0001,
+ 0x81C, 0xEB1C0001,
+ 0x81C, 0xEA1E0001,
+ 0x81C, 0xCD200001,
+ 0x81C, 0xCC220001,
+ 0x81C, 0xCB240001,
+ 0x81C, 0xCA260001,
+ 0x81C, 0xC9280001,
+ 0x81C, 0xC82A0001,
+ 0x81C, 0xC72C0001,
+ 0x81C, 0xC62E0001,
+ 0x81C, 0xA5300001,
+ 0x81C, 0xA4320001,
+ 0x81C, 0xA3340001,
+ 0x81C, 0xA2360001,
+ 0x81C, 0x88380001,
+ 0x81C, 0x873A0001,
+ 0x81C, 0x863C0001,
+ 0x81C, 0x853E0001,
+ 0x81C, 0x84400001,
+ 0x81C, 0x83420001,
+ 0x81C, 0x82440001,
+ 0x81C, 0x81460001,
+ 0x81C, 0x48480001,
+ 0x81C, 0x474A0001,
+ 0x81C, 0x464C0001,
+ 0x81C, 0x454E0001,
+ 0x81C, 0x44500001,
+ 0x81C, 0x43520001,
+ 0x81C, 0x42540001,
+ 0x81C, 0x41560001,
+ 0x81C, 0x25580001,
+ 0x81C, 0x245A0001,
+ 0x81C, 0x235C0001,
+ 0x81C, 0x225E0001,
+ 0x81C, 0x21600001,
+ 0x81C, 0x21620001,
+ 0x81C, 0x21640001,
+ 0x81C, 0x21660001,
+ 0x81C, 0x21680001,
+ 0x81C, 0x216A0001,
+ 0x81C, 0x236C0001,
+ 0x81C, 0x226E0001,
+ 0x81C, 0x21700001,
+ 0x81C, 0x21720001,
+ 0x81C, 0x21740001,
+ 0x81C, 0x21760001,
+ 0x81C, 0x21780001,
+ 0x81C, 0x217A0001,
+ 0x81C, 0x217C0001,
+ 0x81C, 0x217E0001,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFF000001,
+ 0x81C, 0xFF020001,
+ 0x81C, 0xFF040001,
+ 0x81C, 0xFF060001,
+ 0x81C, 0xFF080001,
+ 0x81C, 0xFE0A0001,
+ 0x81C, 0xFD0C0001,
+ 0x81C, 0xFC0E0001,
+ 0x81C, 0xFB100001,
+ 0x81C, 0xFA120001,
+ 0x81C, 0xF9140001,
+ 0x81C, 0xF8160001,
+ 0x81C, 0xF7180001,
+ 0x81C, 0xF61A0001,
+ 0x81C, 0xF51C0001,
+ 0x81C, 0xF41E0001,
+ 0x81C, 0xF3200001,
+ 0x81C, 0xF2220001,
+ 0x81C, 0xF1240001,
+ 0x81C, 0xF0260001,
+ 0x81C, 0xEF280001,
+ 0x81C, 0xEE2A0001,
+ 0x81C, 0xED2C0001,
+ 0x81C, 0xEC2E0001,
+ 0x81C, 0xEB300001,
+ 0x81C, 0xEA320001,
+ 0x81C, 0xE9340001,
+ 0x81C, 0xE8360001,
+ 0x81C, 0xE7380001,
+ 0x81C, 0xE63A0001,
+ 0x81C, 0xE53C0001,
+ 0x81C, 0xC73E0001,
+ 0x81C, 0xC6400001,
+ 0x81C, 0xC5420001,
+ 0x81C, 0xC4440001,
+ 0x81C, 0xC3460001,
+ 0x81C, 0xC2480001,
+ 0x81C, 0xC14A0001,
+ 0x81C, 0xA74C0001,
+ 0x81C, 0xA64E0001,
+ 0x81C, 0xA5500001,
+ 0x81C, 0xA4520001,
+ 0x81C, 0xA3540001,
+ 0x81C, 0xA2560001,
+ 0x81C, 0xA1580001,
+ 0x81C, 0x675A0001,
+ 0x81C, 0x665C0001,
+ 0x81C, 0x655E0001,
+ 0x81C, 0x64600001,
+ 0x81C, 0x63620001,
+ 0x81C, 0x48640001,
+ 0x81C, 0x47660001,
+ 0x81C, 0x46680001,
+ 0x81C, 0x456A0001,
+ 0x81C, 0x446C0001,
+ 0x81C, 0x436E0001,
+ 0x81C, 0x42700001,
+ 0x81C, 0x41720001,
+ 0x81C, 0x41740001,
+ 0x81C, 0x41760001,
+ 0x81C, 0x41780001,
+ 0x81C, 0x417A0001,
+ 0x81C, 0x417C0001,
+ 0x81C, 0x417E0001,
+ 0xB0000000, 0x00000000,
+ 0x80000004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFC800001,
+ 0x81C, 0xFB820001,
+ 0x81C, 0xFA840001,
+ 0x81C, 0xF9860001,
+ 0x81C, 0xF8880001,
+ 0x81C, 0xF78A0001,
+ 0x81C, 0xF68C0001,
+ 0x81C, 0xF58E0001,
+ 0x81C, 0xF4900001,
+ 0x81C, 0xF3920001,
+ 0x81C, 0xF2940001,
+ 0x81C, 0xF1960001,
+ 0x81C, 0xF0980001,
+ 0x81C, 0xEF9A0001,
+ 0x81C, 0xEE9C0001,
+ 0x81C, 0xED9E0001,
+ 0x81C, 0xECA00001,
+ 0x81C, 0xEBA20001,
+ 0x81C, 0xEAA40001,
+ 0x81C, 0xE9A60001,
+ 0x81C, 0xE8A80001,
+ 0x81C, 0xE7AA0001,
+ 0x81C, 0xE6AC0001,
+ 0x81C, 0xE5AE0001,
+ 0x81C, 0xE4B00001,
+ 0x81C, 0xE3B20001,
+ 0x81C, 0xA8B40001,
+ 0x81C, 0xA7B60001,
+ 0x81C, 0xA6B80001,
+ 0x81C, 0xA5BA0001,
+ 0x81C, 0xA4BC0001,
+ 0x81C, 0xA3BE0001,
+ 0x81C, 0xA2C00001,
+ 0x81C, 0xA1C20001,
+ 0x81C, 0x68C40001,
+ 0x81C, 0x67C60001,
+ 0x81C, 0x66C80001,
+ 0x81C, 0x65CA0001,
+ 0x81C, 0x64CC0001,
+ 0x81C, 0x47CE0001,
+ 0x81C, 0x46D00001,
+ 0x81C, 0x45D20001,
+ 0x81C, 0x44D40001,
+ 0x81C, 0x43D60001,
+ 0x81C, 0x42D80001,
+ 0x81C, 0x08DA0001,
+ 0x81C, 0x07DC0001,
+ 0x81C, 0x06DE0001,
+ 0x81C, 0x05E00001,
+ 0x81C, 0x04E20001,
+ 0x81C, 0x03E40001,
+ 0x81C, 0x02E60001,
+ 0x81C, 0x01E80001,
+ 0x81C, 0x01EA0001,
+ 0x81C, 0x01EC0001,
+ 0x81C, 0x01EE0001,
+ 0x81C, 0x01F00001,
+ 0x81C, 0x01F20001,
+ 0x81C, 0x01F40001,
+ 0x81C, 0x01F60001,
+ 0x81C, 0x01F80001,
+ 0x81C, 0x01FA0001,
+ 0x81C, 0x01FC0001,
+ 0x81C, 0x01FE0001,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFF800001,
+ 0x81C, 0xFF820001,
+ 0x81C, 0xFF840001,
+ 0x81C, 0xFE860001,
+ 0x81C, 0xFD880001,
+ 0x81C, 0xFC8A0001,
+ 0x81C, 0xFB8C0001,
+ 0x81C, 0xFA8E0001,
+ 0x81C, 0xF9900001,
+ 0x81C, 0xF8920001,
+ 0x81C, 0xF7940001,
+ 0x81C, 0xF6960001,
+ 0x81C, 0xF5980001,
+ 0x81C, 0xF49A0001,
+ 0x81C, 0xF39C0001,
+ 0x81C, 0xF29E0001,
+ 0x81C, 0xF1A00001,
+ 0x81C, 0xF0A20001,
+ 0x81C, 0xEFA40001,
+ 0x81C, 0xEEA60001,
+ 0x81C, 0xEDA80001,
+ 0x81C, 0xECAA0001,
+ 0x81C, 0xEBAC0001,
+ 0x81C, 0xEAAE0001,
+ 0x81C, 0xE9B00001,
+ 0x81C, 0xE8B20001,
+ 0x81C, 0xE7B40001,
+ 0x81C, 0xE6B60001,
+ 0x81C, 0xE5B80001,
+ 0x81C, 0xE4BA0001,
+ 0x81C, 0xE3BC0001,
+ 0x81C, 0xA8BE0001,
+ 0x81C, 0xA7C00001,
+ 0x81C, 0xA6C20001,
+ 0x81C, 0xA5C40001,
+ 0x81C, 0xA4C60001,
+ 0x81C, 0xA3C80001,
+ 0x81C, 0xA2CA0001,
+ 0x81C, 0xA1CC0001,
+ 0x81C, 0x68CE0001,
+ 0x81C, 0x67D00001,
+ 0x81C, 0x66D20001,
+ 0x81C, 0x65D40001,
+ 0x81C, 0x64D60001,
+ 0x81C, 0x47D80001,
+ 0x81C, 0x46DA0001,
+ 0x81C, 0x45DC0001,
+ 0x81C, 0x44DE0001,
+ 0x81C, 0x43E00001,
+ 0x81C, 0x42E20001,
+ 0x81C, 0x08E40001,
+ 0x81C, 0x07E60001,
+ 0x81C, 0x06E80001,
+ 0x81C, 0x05EA0001,
+ 0x81C, 0x04EC0001,
+ 0x81C, 0x03EE0001,
+ 0x81C, 0x02F00001,
+ 0x81C, 0x01F20001,
+ 0x81C, 0x01F40001,
+ 0x81C, 0x01F60001,
+ 0x81C, 0x01F80001,
+ 0x81C, 0x01FA0001,
+ 0x81C, 0x01FC0001,
+ 0x81C, 0x01FE0001,
+ 0xB0000000, 0x00000000,
+ 0xC50, 0x00000022,
+ 0xC50, 0x00000020,
+ 0xE50, 0x00000022,
+ 0xE50, 0x00000020,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8812a_agc, rtw_phy_cfg_agc);
+
+static const u32 rtw8812a_agc_diff_lb[] = {
+ 0x80000004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0x47CE0001,
+ 0x81C, 0x46D00001,
+ 0x81C, 0x45D20001,
+ 0x81C, 0x44D40001,
+ 0x81C, 0x43D60001,
+ 0x81C, 0x42D80001,
+ 0x81C, 0x08DA0001,
+ 0x81C, 0x07DC0001,
+ 0x81C, 0x06DE0001,
+ 0x81C, 0x05E00001,
+ 0x81C, 0x04E20001,
+ 0x81C, 0x03E40001,
+ 0x81C, 0x02E60001,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0x47D80001,
+ 0x81C, 0x46DA0001,
+ 0x81C, 0x45DC0001,
+ 0x81C, 0x44DE0001,
+ 0x81C, 0x43E00001,
+ 0x81C, 0x42E20001,
+ 0x81C, 0x08E40001,
+ 0x81C, 0x07E60001,
+ 0x81C, 0x06E80001,
+ 0x81C, 0x05EA0001,
+ 0x81C, 0x04EC0001,
+ 0x81C, 0x03EE0001,
+ 0x81C, 0x02F00001,
+ 0xB0000000, 0x00000000,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_lb, rtw_phy_cfg_agc);
+
+static const u32 rtw8812a_agc_diff_hb[] = {
+ 0x80000004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0x45CE0001,
+ 0x81C, 0x44D00001,
+ 0x81C, 0x43D20001,
+ 0x81C, 0x42D40001,
+ 0x81C, 0x08D60001,
+ 0x81C, 0x07D80001,
+ 0x81C, 0x06DA0001,
+ 0x81C, 0x05DC0001,
+ 0x81C, 0x04DE0001,
+ 0x81C, 0x03E00001,
+ 0x81C, 0x02E20001,
+ 0x81C, 0x01E40001,
+ 0x81C, 0x01E60001,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0x45D80001,
+ 0x81C, 0x44DA0001,
+ 0x81C, 0x43DC0001,
+ 0x81C, 0x42DE0001,
+ 0x81C, 0x08E00001,
+ 0x81C, 0x07E20001,
+ 0x81C, 0x06E40001,
+ 0x81C, 0x05E60001,
+ 0x81C, 0x04E80001,
+ 0x81C, 0x03EA0001,
+ 0x81C, 0x02EC0001,
+ 0x81C, 0x01EE0001,
+ 0x81C, 0x01F00001,
+ 0xB0000000, 0x00000000,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_hb, rtw_phy_cfg_agc);
+
+static const u32 rtw8812a_bb[] = {
+ 0x800, 0x8020D010,
+ 0x804, 0x080112E0,
+ 0x808, 0x0E028233,
+ 0x80C, 0x12131113,
+ 0x810, 0x20101263,
+ 0x814, 0x020C3D10,
+ 0x818, 0x03A00385,
+ 0x820, 0x00000000,
+ 0x824, 0x00030FE0,
+ 0x828, 0x00000000,
+ 0x82C, 0x002083DD,
+ 0x830, 0x2EAAEEB8,
+ 0x834, 0x0037A706,
+ 0x838, 0x06C89B44,
+ 0x83C, 0x0000095B,
+ 0x840, 0xC0000001,
+ 0x844, 0x40003CDE,
+ 0x848, 0x6210FF8B,
+ 0x84C, 0x6CFDFFB8,
+ 0x850, 0x28874706,
+ 0x854, 0x0001520C,
+ 0x858, 0x8060E000,
+ 0x85C, 0x74210168,
+ 0x860, 0x6929C321,
+ 0x864, 0x79727432,
+ 0x868, 0x8CA7A314,
+ 0x86C, 0x338C2878,
+ 0x870, 0x03333333,
+ 0x874, 0x31602C2E,
+ 0x878, 0x00003152,
+ 0x87C, 0x000FC000,
+ 0x8A0, 0x00000013,
+ 0x8A4, 0x7F7F7F7F,
+ 0x8A8, 0xA202033E,
+ 0x8AC, 0x0FF0FA0A,
+ 0x8B0, 0x00000600,
+ 0x8B4, 0x000FC080,
+ 0x8B8, 0x6C10D7FF,
+ 0x8BC, 0x4CA520A3,
+ 0x8C0, 0x27F00020,
+ 0x8C4, 0x00000000,
+ 0x8C8, 0x00012D69,
+ 0x8CC, 0x08248492,
+ 0x8D0, 0x0000B800,
+ 0x8DC, 0x00000000,
+ 0x8D4, 0x940008A0,
+ 0x8D8, 0x290B5612,
+ 0x8F8, 0x400002C0,
+ 0x8FC, 0x00000000,
+ 0x900, 0x00000701,
+ 0x90C, 0x00000000,
+ 0x910, 0x0000FC00,
+ 0x914, 0x00000404,
+ 0x918, 0x1C1028C0,
+ 0x91C, 0x64B11A1C,
+ 0x920, 0xE0767233,
+ 0x924, 0x055AA500,
+ 0x928, 0x00000004,
+ 0x92C, 0xFFFE0000,
+ 0x930, 0xFFFFFFFE,
+ 0x934, 0x001FFFFF,
+ 0x960, 0x00000000,
+ 0x964, 0x00000000,
+ 0x968, 0x00000000,
+ 0x96C, 0x00000000,
+ 0x970, 0x801FFFFF,
+ 0x978, 0x00000000,
+ 0x97C, 0x00000000,
+ 0x980, 0x00000000,
+ 0x984, 0x00000000,
+ 0x988, 0x00000000,
+ 0x990, 0x27100000,
+ 0x994, 0xFFFF0100,
+ 0x998, 0xFFFFFF5C,
+ 0x99C, 0xFFFFFFFF,
+ 0x9A0, 0x000000FF,
+ 0x9A4, 0x00080080,
+ 0x9A8, 0x00000000,
+ 0x9AC, 0x00000000,
+ 0x9B0, 0x81081008,
+ 0x9B4, 0x00000000,
+ 0x9B8, 0x01081008,
+ 0x9BC, 0x01081008,
+ 0x9D0, 0x00000000,
+ 0x9D4, 0x00000000,
+ 0x9D8, 0x00000000,
+ 0x9DC, 0x00000000,
+ 0x9E4, 0x00000003,
+ 0x9E8, 0x000002D5,
+ 0xA00, 0x00D047C8,
+ 0xA04, 0x01FF000C,
+ 0xA08, 0x8C838300,
+ 0xA0C, 0x2E7F000F,
+ 0xA10, 0x9500BB78,
+ 0xA14, 0x11144028,
+ 0xA18, 0x00881117,
+ 0xA1C, 0x89140F00,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1217,
+ 0xA28, 0x00000305,
+ 0xA2C, 0x00900000,
+ 0xA70, 0x101FFF00,
+ 0xA74, 0x00000008,
+ 0xA78, 0x00000900,
+ 0xA7C, 0x225B0606,
+ 0xA80, 0x218075B2,
+ 0xA84, 0x001F8C80,
+ 0xB00, 0x03100000,
+ 0xB04, 0x0000B000,
+ 0xB08, 0xAE0201EB,
+ 0xB0C, 0x01003207,
+ 0xB10, 0x00009807,
+ 0xB14, 0x01000000,
+ 0xB18, 0x00000002,
+ 0xB1C, 0x00000002,
+ 0xB20, 0x0000001F,
+ 0xB24, 0x03020100,
+ 0xB28, 0x07060504,
+ 0xB2C, 0x0B0A0908,
+ 0xB30, 0x0F0E0D0C,
+ 0xB34, 0x13121110,
+ 0xB38, 0x17161514,
+ 0xB3C, 0x0000003A,
+ 0xB40, 0x00000000,
+ 0xB44, 0x00000000,
+ 0xB48, 0x13000032,
+ 0xB4C, 0x48080000,
+ 0xB50, 0x00000000,
+ 0xB54, 0x00000000,
+ 0xB58, 0x00000000,
+ 0xB5C, 0x00000000,
+ 0xC00, 0x00000007,
+ 0xC04, 0x00042020,
+ 0xC08, 0x80410231,
+ 0xC0C, 0x00000000,
+ 0xC10, 0x00000100,
+ 0xC14, 0x01000000,
+ 0xC1C, 0x40000003,
+ 0xC20, 0x12121212,
+ 0xC24, 0x12121212,
+ 0xC28, 0x12121212,
+ 0xC2C, 0x12121212,
+ 0xC30, 0x12121212,
+ 0xC34, 0x12121212,
+ 0xC38, 0x12121212,
+ 0xC3C, 0x12121212,
+ 0xC40, 0x12121212,
+ 0xC44, 0x12121212,
+ 0xC48, 0x12121212,
+ 0xC4C, 0x12121212,
+ 0xC50, 0x00000020,
+ 0xC54, 0x0008121C,
+ 0xC58, 0x30000C1C,
+ 0xC5C, 0x00000058,
+ 0xC60, 0x34344443,
+ 0xC64, 0x07003333,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0xC68, 0x59791979,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0xC68, 0x59791979,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xC68, 0x59791979,
+ 0x90000004, 0x00000000, 0x40000000, 0x00000000,
+ 0xC68, 0x59791979,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC68, 0x59791979,
+ 0x90000001, 0x00000005, 0x40000000, 0x00000000,
+ 0xC68, 0x59791979,
+ 0xA0000000, 0x00000000,
+ 0xC68, 0x59799979,
+ 0xB0000000, 0x00000000,
+ 0xC6C, 0x59795979,
+ 0xC70, 0x19795979,
+ 0xC74, 0x19795979,
+ 0xC78, 0x19791979,
+ 0xC7C, 0x19791979,
+ 0xC80, 0x19791979,
+ 0xC84, 0x19791979,
+ 0xC94, 0x0100005C,
+ 0xC98, 0x00000000,
+ 0xC9C, 0x00000000,
+ 0xCA0, 0x00000029,
+ 0xCA4, 0x08040201,
+ 0xCA8, 0x80402010,
+ 0xCB0, 0x77547777,
+ 0xCB4, 0x00000077,
+ 0xCB8, 0x00508242,
+ 0xE00, 0x00000007,
+ 0xE04, 0x00042020,
+ 0xE08, 0x80410231,
+ 0xE0C, 0x00000000,
+ 0xE10, 0x00000100,
+ 0xE14, 0x01000000,
+ 0xE1C, 0x40000003,
+ 0xE20, 0x12121212,
+ 0xE24, 0x12121212,
+ 0xE28, 0x12121212,
+ 0xE2C, 0x12121212,
+ 0xE30, 0x12121212,
+ 0xE34, 0x12121212,
+ 0xE38, 0x12121212,
+ 0xE3C, 0x12121212,
+ 0xE40, 0x12121212,
+ 0xE44, 0x12121212,
+ 0xE48, 0x12121212,
+ 0xE4C, 0x12121212,
+ 0xE50, 0x00000020,
+ 0xE54, 0x0008121C,
+ 0xE58, 0x30000C1C,
+ 0xE5C, 0x00000058,
+ 0xE60, 0x34344443,
+ 0xE64, 0x07003333,
+ 0xE68, 0x59791979,
+ 0xE6C, 0x59795979,
+ 0xE70, 0x19795979,
+ 0xE74, 0x19795979,
+ 0xE78, 0x19791979,
+ 0xE7C, 0x19791979,
+ 0xE80, 0x19791979,
+ 0xE84, 0x19791979,
+ 0xE94, 0x0100005C,
+ 0xE98, 0x00000000,
+ 0xE9C, 0x00000000,
+ 0xEA0, 0x00000029,
+ 0xEA4, 0x08040201,
+ 0xEA8, 0x80402010,
+ 0xEB0, 0x77547777,
+ 0xEB4, 0x00000077,
+ 0xEB8, 0x00508242,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8812a_bb, rtw_phy_cfg_bb);
+
+static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg[] = {
+ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, },
+ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, },
+ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638, },
+ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, },
+ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, },
+ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, },
+ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, },
+ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, },
+ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, },
+ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, },
+ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, },
+ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, },
+ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840, },
+ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, },
+ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638, },
+ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, },
+ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, },
+ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, },
+ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, },
+ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, },
+ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, },
+ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, },
+ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, },
+ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, },
+ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, },
+ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640, },
+ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, },
+ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, },
+ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, },
+ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, },
+ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, },
+ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, },
+ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, },
+ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, },
+ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, },
+ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, },
+ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640, },
+ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, },
+ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, },
+ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, },
+ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, },
+ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, },
+ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, },
+ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, },
+ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, },
+ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, },
+};
+
+RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg);
+
+static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg_rfe3[] = {
+ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, },
+ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, },
+ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, },
+ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, },
+ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303232, },
+ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, },
+ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, },
+ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, },
+ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303232, },
+ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, },
+ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32323232, },
+ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, },
+ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, },
+ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, },
+ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, },
+ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, },
+ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303232, },
+ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, },
+ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, },
+ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, },
+ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303232, },
+ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, },
+ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32323232, },
+ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, },
+ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, },
+ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, },
+ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, },
+ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, },
+ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, },
+ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322222, },
+ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303232, },
+ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22222426, },
+ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, },
+ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, },
+ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, },
+ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, },
+ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, },
+ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, },
+ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, },
+ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, },
+ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322222, },
+ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303232, },
+ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22222426, },
+};
+
+RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg_rfe3);
+
+static const u32 rtw8812a_rf_a[] = {
+ 0x000, 0x00010000,
+ 0x018, 0x0001712A,
+ 0x056, 0x00051CF2,
+ 0x066, 0x00040000,
+ 0x01E, 0x00080000,
+ 0x089, 0x00000080,
+ 0x80000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x00014B3A,
+ 0x90000001, 0x00000005, 0x40000000, 0x00000000,
+ 0x086, 0x00014B3A,
+ 0xA0000000, 0x00000000,
+ 0x086, 0x00014B38,
+ 0xB0000000, 0x00000000,
+ 0x80000004, 0x00000000, 0x40000000, 0x00000000,
+ 0x08B, 0x00080180,
+ 0xA0000000, 0x00000000,
+ 0x08B, 0x00087180,
+ 0xB0000000, 0x00000000,
+ 0x0B1, 0x0001FC1A,
+ 0x0B3, 0x000F0810,
+ 0x0B4, 0x0001A78D,
+ 0x0BA, 0x00086180,
+ 0x018, 0x00000006,
+ 0x0EF, 0x00002000,
+ 0x80000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x0003F218,
+ 0x03B, 0x00030A58,
+ 0x03B, 0x0002FA58,
+ 0x03B, 0x00022590,
+ 0x03B, 0x0001FA50,
+ 0x03B, 0x00010248,
+ 0x03B, 0x00008240,
+ 0x90000001, 0x00000005, 0x40000000, 0x00000000,
+ 0x03B, 0x0003F218,
+ 0x03B, 0x00030A58,
+ 0x03B, 0x0002FA58,
+ 0x03B, 0x00022590,
+ 0x03B, 0x0001FA50,
+ 0x03B, 0x00010248,
+ 0x03B, 0x00008240,
+ 0xA0000000, 0x00000000,
+ 0x03B, 0x00038A58,
+ 0x03B, 0x00037A58,
+ 0x03B, 0x0002A590,
+ 0x03B, 0x00027A50,
+ 0x03B, 0x00018248,
+ 0x03B, 0x00010240,
+ 0x03B, 0x00008240,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x80000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A4EE,
+ 0x034, 0x00009076,
+ 0x034, 0x00008073,
+ 0x034, 0x00007070,
+ 0x034, 0x0000606D,
+ 0x034, 0x0000506A,
+ 0x034, 0x00004049,
+ 0x034, 0x00003046,
+ 0x034, 0x00002028,
+ 0x034, 0x00001025,
+ 0x034, 0x00000022,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0000ADF4,
+ 0x034, 0x00009DF1,
+ 0x034, 0x00008DEE,
+ 0x034, 0x00007DEB,
+ 0x034, 0x00006DE8,
+ 0x034, 0x00005DE5,
+ 0x034, 0x00004DE2,
+ 0x034, 0x00003CE6,
+ 0x034, 0x000024E7,
+ 0x034, 0x000014E4,
+ 0x034, 0x000004E1,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x000020A2,
+ 0x0DF, 0x00000080,
+ 0x035, 0x00000192,
+ 0x035, 0x00008192,
+ 0x035, 0x00010192,
+ 0x036, 0x00000024,
+ 0x036, 0x00008024,
+ 0x036, 0x00010024,
+ 0x036, 0x00018024,
+ 0x0EF, 0x00000000,
+ 0x051, 0x00000C21,
+ 0x052, 0x000006D9,
+ 0x053, 0x000FC649,
+ 0x054, 0x0000017E,
+ 0x0EF, 0x00000002,
+ 0x008, 0x00008400,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00001000,
+ 0x03A, 0x00000080,
+ 0x03B, 0x0003A02C,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000400,
+ 0x03B, 0x0003202C,
+ 0x03C, 0x00010000,
+ 0x03A, 0x000000A0,
+ 0x03B, 0x0002B064,
+ 0x03C, 0x00004000,
+ 0x03A, 0x000000D8,
+ 0x03B, 0x00023070,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000468,
+ 0x03B, 0x0001B870,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000098,
+ 0x03B, 0x00012085,
+ 0x03C, 0x000E4000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x0000A080,
+ 0x03C, 0x000F0000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x00002080,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000080,
+ 0x03B, 0x0007A02C,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000400,
+ 0x03B, 0x0007202C,
+ 0x03C, 0x00010000,
+ 0x03A, 0x000000A0,
+ 0x03B, 0x0006B064,
+ 0x03C, 0x00004000,
+ 0x03A, 0x000000D8,
+ 0x03B, 0x00063070,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000468,
+ 0x03B, 0x0005B870,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000098,
+ 0x03B, 0x00052085,
+ 0x03C, 0x000E4000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x0004A080,
+ 0x03C, 0x000F0000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x00042080,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000080,
+ 0x03B, 0x000BA02C,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000400,
+ 0x03B, 0x000B202C,
+ 0x03C, 0x00010000,
+ 0x03A, 0x000000A0,
+ 0x03B, 0x000AB064,
+ 0x03C, 0x00004000,
+ 0x03A, 0x000000D8,
+ 0x03B, 0x000A3070,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000468,
+ 0x03B, 0x0009B870,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000098,
+ 0x03B, 0x00092085,
+ 0x03C, 0x000E4000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x0008A080,
+ 0x03C, 0x000F0000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x00082080,
+ 0x03C, 0x00010000,
+ 0x0EF, 0x00001100,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004A0B2,
+ 0x034, 0x000490AF,
+ 0x034, 0x00048070,
+ 0x034, 0x0004706D,
+ 0x034, 0x00046050,
+ 0x034, 0x0004504D,
+ 0x034, 0x0004404A,
+ 0x034, 0x00043047,
+ 0x034, 0x0004200A,
+ 0x034, 0x00041007,
+ 0x034, 0x00040004,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004A0B2,
+ 0x034, 0x000490AF,
+ 0x034, 0x00048070,
+ 0x034, 0x0004706D,
+ 0x034, 0x0004604D,
+ 0x034, 0x0004504A,
+ 0x034, 0x00044047,
+ 0x034, 0x00043044,
+ 0x034, 0x00042007,
+ 0x034, 0x00041004,
+ 0x034, 0x00040001,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0004ADF5,
+ 0x034, 0x00049DF2,
+ 0x034, 0x00048DEF,
+ 0x034, 0x00047DEC,
+ 0x034, 0x00046DE9,
+ 0x034, 0x00045DE6,
+ 0x034, 0x00044DE3,
+ 0x034, 0x000438C8,
+ 0x034, 0x000428C5,
+ 0x034, 0x000418C2,
+ 0x034, 0x000408C0,
+ 0xB0000000, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002A0B2,
+ 0x034, 0x000290AF,
+ 0x034, 0x00028070,
+ 0x034, 0x0002706D,
+ 0x034, 0x00026050,
+ 0x034, 0x0002504D,
+ 0x034, 0x0002404A,
+ 0x034, 0x00023047,
+ 0x034, 0x0002200A,
+ 0x034, 0x00021007,
+ 0x034, 0x00020004,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002A0B4,
+ 0x034, 0x000290B1,
+ 0x034, 0x00028072,
+ 0x034, 0x0002706F,
+ 0x034, 0x0002604F,
+ 0x034, 0x0002504C,
+ 0x034, 0x00024049,
+ 0x034, 0x00023046,
+ 0x034, 0x00022009,
+ 0x034, 0x00021006,
+ 0x034, 0x00020003,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0002ADF5,
+ 0x034, 0x00029DF2,
+ 0x034, 0x00028DEF,
+ 0x034, 0x00027DEC,
+ 0x034, 0x00026DE9,
+ 0x034, 0x00025DE6,
+ 0x034, 0x00024DE3,
+ 0x034, 0x000238C8,
+ 0x034, 0x000228C5,
+ 0x034, 0x000218C2,
+ 0x034, 0x000208C0,
+ 0xB0000000, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A0B2,
+ 0x034, 0x000090AF,
+ 0x034, 0x00008070,
+ 0x034, 0x0000706D,
+ 0x034, 0x00006050,
+ 0x034, 0x0000504D,
+ 0x034, 0x0000404A,
+ 0x034, 0x00003047,
+ 0x034, 0x0000200A,
+ 0x034, 0x00001007,
+ 0x034, 0x00000004,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A0B2,
+ 0x034, 0x000090AF,
+ 0x034, 0x00008070,
+ 0x034, 0x0000706D,
+ 0x034, 0x0000604D,
+ 0x034, 0x0000504A,
+ 0x034, 0x00004047,
+ 0x034, 0x00003044,
+ 0x034, 0x00002007,
+ 0x034, 0x00001004,
+ 0x034, 0x00000001,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0000AFF7,
+ 0x034, 0x00009DF7,
+ 0x034, 0x00008DF4,
+ 0x034, 0x00007DF1,
+ 0x034, 0x00006DEE,
+ 0x034, 0x00005DEB,
+ 0x034, 0x00004DE8,
+ 0x034, 0x000038CC,
+ 0x034, 0x000028C9,
+ 0x034, 0x000018C6,
+ 0x034, 0x000008C3,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x035, 0x000001D4,
+ 0x035, 0x000081D4,
+ 0x035, 0x000101D4,
+ 0x035, 0x000201B4,
+ 0x035, 0x000281B4,
+ 0x035, 0x000301B4,
+ 0x035, 0x000401B4,
+ 0x035, 0x000481B4,
+ 0x035, 0x000501B4,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x035, 0x000001D4,
+ 0x035, 0x000081D4,
+ 0x035, 0x000101D4,
+ 0x035, 0x000201B4,
+ 0x035, 0x000281B4,
+ 0x035, 0x000301B4,
+ 0x035, 0x000401B4,
+ 0x035, 0x000481B4,
+ 0x035, 0x000501B4,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x035, 0x00000188,
+ 0x035, 0x00008147,
+ 0x035, 0x00010147,
+ 0x035, 0x000201D7,
+ 0x035, 0x000281D7,
+ 0x035, 0x000301D7,
+ 0x035, 0x000401D8,
+ 0x035, 0x000481D8,
+ 0x035, 0x000501D8,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x036, 0x00004BFB,
+ 0x036, 0x0000CBFB,
+ 0x036, 0x00014BFB,
+ 0x036, 0x0001CBFB,
+ 0x036, 0x00024F4B,
+ 0x036, 0x0002CF4B,
+ 0x036, 0x00034F4B,
+ 0x036, 0x0003CF4B,
+ 0x036, 0x00044F4B,
+ 0x036, 0x0004CF4B,
+ 0x036, 0x00054F4B,
+ 0x036, 0x0005CF4B,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x036, 0x00004BFB,
+ 0x036, 0x0000CBFB,
+ 0x036, 0x00014BFB,
+ 0x036, 0x0001CBFB,
+ 0x036, 0x00024F4B,
+ 0x036, 0x0002CF4B,
+ 0x036, 0x00034F4B,
+ 0x036, 0x0003CF4B,
+ 0x036, 0x00044F4B,
+ 0x036, 0x0004CF4B,
+ 0x036, 0x00054F4B,
+ 0x036, 0x0005CF4B,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x036, 0x00084EB4,
+ 0x036, 0x0008CC35,
+ 0x036, 0x00094C35,
+ 0x036, 0x0009CC35,
+ 0x036, 0x000A4C35,
+ 0x036, 0x000ACC35,
+ 0x036, 0x000B4C35,
+ 0x036, 0x000BCC35,
+ 0x036, 0x000C4C34,
+ 0x036, 0x000CCC35,
+ 0x036, 0x000D4C35,
+ 0x036, 0x000DCC35,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00000008,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000002CC,
+ 0x03C, 0x00000522,
+ 0x03C, 0x00000902,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000002CC,
+ 0x03C, 0x00000522,
+ 0x03C, 0x00000902,
+ 0xA0000000, 0x00000000,
+ 0x03C, 0x000002A8,
+ 0x03C, 0x000005A2,
+ 0x03C, 0x00000880,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000002,
+ 0x0DF, 0x00000080,
+ 0x01F, 0x00000064,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000FDD43,
+ 0x062, 0x00038F4B,
+ 0x063, 0x00032117,
+ 0x064, 0x000194AC,
+ 0x065, 0x000931D1,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x061, 0x000FDD43,
+ 0x062, 0x00038F4B,
+ 0x063, 0x00032117,
+ 0x064, 0x000194AC,
+ 0x065, 0x000931D2,
+ 0xA0000000, 0x00000000,
+ 0x061, 0x000E5D53,
+ 0x062, 0x00038FCD,
+ 0x063, 0x000114EB,
+ 0x064, 0x000196AC,
+ 0x065, 0x000911D7,
+ 0xB0000000, 0x00000000,
+ 0x008, 0x00008400,
+ 0x01C, 0x000739D2,
+ 0x0B4, 0x0001E78D,
+ 0x018, 0x0001F12A,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x0B4, 0x0001A78D,
+ 0x018, 0x0001712A,
+};
+
+RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_a, A);
+
+static const u32 rtw8812a_rf_b[] = {
+ 0x056, 0x00051CF2,
+ 0x066, 0x00040000,
+ 0x089, 0x00000080,
+ 0x80000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x00014B3A,
+ 0x90000001, 0x00000005, 0x40000000, 0x00000000,
+ 0x086, 0x00014B3A,
+ 0xA0000000, 0x00000000,
+ 0x086, 0x00014B38,
+ 0xB0000000, 0x00000000,
+ 0x80000004, 0x00000000, 0x40000000, 0x00000000,
+ 0x08B, 0x00080180,
+ 0xA0000000, 0x00000000,
+ 0x08B, 0x00087180,
+ 0xB0000000, 0x00000000,
+ 0x018, 0x00000006,
+ 0x0EF, 0x00002000,
+ 0x80000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x0003F218,
+ 0x03B, 0x00030A58,
+ 0x03B, 0x0002FA58,
+ 0x03B, 0x00022590,
+ 0x03B, 0x0001FA50,
+ 0x03B, 0x00010248,
+ 0x03B, 0x00008240,
+ 0x90000001, 0x00000005, 0x40000000, 0x00000000,
+ 0x03B, 0x0003F218,
+ 0x03B, 0x00030A58,
+ 0x03B, 0x0002FA58,
+ 0x03B, 0x00022590,
+ 0x03B, 0x0001FA50,
+ 0x03B, 0x00010248,
+ 0x03B, 0x00008240,
+ 0xA0000000, 0x00000000,
+ 0x03B, 0x00038A58,
+ 0x03B, 0x00037A58,
+ 0x03B, 0x0002A590,
+ 0x03B, 0x00027A50,
+ 0x03B, 0x00018248,
+ 0x03B, 0x00010240,
+ 0x03B, 0x00008240,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x80000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A4EE,
+ 0x034, 0x00009076,
+ 0x034, 0x00008073,
+ 0x034, 0x00007070,
+ 0x034, 0x0000606D,
+ 0x034, 0x0000506A,
+ 0x034, 0x00004049,
+ 0x034, 0x00003046,
+ 0x034, 0x00002028,
+ 0x034, 0x00001025,
+ 0x034, 0x00000022,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0000ADF4,
+ 0x034, 0x00009DF1,
+ 0x034, 0x00008DEE,
+ 0x034, 0x00007DEB,
+ 0x034, 0x00006DE8,
+ 0x034, 0x00005DE5,
+ 0x034, 0x00004DE2,
+ 0x034, 0x00003CE6,
+ 0x034, 0x000024E7,
+ 0x034, 0x000014E4,
+ 0x034, 0x000004E1,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x000020A2,
+ 0x0DF, 0x00000080,
+ 0x035, 0x00000192,
+ 0x035, 0x00008192,
+ 0x035, 0x00010192,
+ 0x036, 0x00000024,
+ 0x036, 0x00008024,
+ 0x036, 0x00010024,
+ 0x036, 0x00018024,
+ 0x0EF, 0x00000000,
+ 0x051, 0x00000C21,
+ 0x052, 0x000006D9,
+ 0x053, 0x000FC649,
+ 0x054, 0x0000017E,
+ 0x0EF, 0x00000002,
+ 0x008, 0x00008400,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00001000,
+ 0x03A, 0x00000080,
+ 0x03B, 0x0003A02C,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000400,
+ 0x03B, 0x0003202C,
+ 0x03C, 0x00010000,
+ 0x03A, 0x000000A0,
+ 0x03B, 0x0002B064,
+ 0x03C, 0x00004000,
+ 0x03A, 0x000000D8,
+ 0x03B, 0x00023070,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000468,
+ 0x03B, 0x0001B870,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000098,
+ 0x03B, 0x00012085,
+ 0x03C, 0x000E4000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x0000A080,
+ 0x03C, 0x000F0000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x00002080,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000080,
+ 0x03B, 0x0007A02C,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000400,
+ 0x03B, 0x0007202C,
+ 0x03C, 0x00010000,
+ 0x03A, 0x000000A0,
+ 0x03B, 0x0006B064,
+ 0x03C, 0x00004000,
+ 0x03A, 0x000000D8,
+ 0x03B, 0x00063070,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000468,
+ 0x03B, 0x0005B870,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000098,
+ 0x03B, 0x00052085,
+ 0x03C, 0x000E4000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x0004A080,
+ 0x03C, 0x000F0000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x00042080,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000080,
+ 0x03B, 0x000BA02C,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000400,
+ 0x03B, 0x000B202C,
+ 0x03C, 0x00010000,
+ 0x03A, 0x000000A0,
+ 0x03B, 0x000AB064,
+ 0x03C, 0x00004000,
+ 0x03A, 0x000000D8,
+ 0x03B, 0x000A3070,
+ 0x03C, 0x00004000,
+ 0x03A, 0x00000468,
+ 0x03B, 0x0009B870,
+ 0x03C, 0x00010000,
+ 0x03A, 0x00000098,
+ 0x03B, 0x00092085,
+ 0x03C, 0x000E4000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x0008A080,
+ 0x03C, 0x000F0000,
+ 0x03A, 0x00000418,
+ 0x03B, 0x00082080,
+ 0x03C, 0x00010000,
+ 0x0EF, 0x00001100,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004A0B2,
+ 0x034, 0x000490AF,
+ 0x034, 0x00048070,
+ 0x034, 0x0004706D,
+ 0x034, 0x00046050,
+ 0x034, 0x0004504D,
+ 0x034, 0x0004404A,
+ 0x034, 0x00043047,
+ 0x034, 0x0004200A,
+ 0x034, 0x00041007,
+ 0x034, 0x00040004,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004A0B1,
+ 0x034, 0x000490AE,
+ 0x034, 0x0004806F,
+ 0x034, 0x0004706C,
+ 0x034, 0x0004604C,
+ 0x034, 0x00045049,
+ 0x034, 0x00044046,
+ 0x034, 0x00043043,
+ 0x034, 0x00042006,
+ 0x034, 0x00041003,
+ 0x034, 0x00040000,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0004ADF5,
+ 0x034, 0x00049DF2,
+ 0x034, 0x00048DEF,
+ 0x034, 0x00047DEC,
+ 0x034, 0x00046DE9,
+ 0x034, 0x00045DE6,
+ 0x034, 0x00044DE3,
+ 0x034, 0x000438C8,
+ 0x034, 0x000428C5,
+ 0x034, 0x000418C2,
+ 0x034, 0x000408C0,
+ 0xB0000000, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002A0B2,
+ 0x034, 0x000290AF,
+ 0x034, 0x00028070,
+ 0x034, 0x0002706D,
+ 0x034, 0x00026050,
+ 0x034, 0x0002504D,
+ 0x034, 0x0002404A,
+ 0x034, 0x00023047,
+ 0x034, 0x0002200A,
+ 0x034, 0x00021007,
+ 0x034, 0x00020004,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002A0B3,
+ 0x034, 0x000290B0,
+ 0x034, 0x00028071,
+ 0x034, 0x0002706E,
+ 0x034, 0x0002604E,
+ 0x034, 0x0002504B,
+ 0x034, 0x00024048,
+ 0x034, 0x00023045,
+ 0x034, 0x00022008,
+ 0x034, 0x00021005,
+ 0x034, 0x00020002,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0002ADF5,
+ 0x034, 0x00029DF2,
+ 0x034, 0x00028DEF,
+ 0x034, 0x00027DEC,
+ 0x034, 0x00026DE9,
+ 0x034, 0x00025DE6,
+ 0x034, 0x00024DE3,
+ 0x034, 0x000238C8,
+ 0x034, 0x000228C5,
+ 0x034, 0x000218C2,
+ 0x034, 0x000208C0,
+ 0xB0000000, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A0B2,
+ 0x034, 0x000090AF,
+ 0x034, 0x00008070,
+ 0x034, 0x0000706D,
+ 0x034, 0x00006050,
+ 0x034, 0x0000504D,
+ 0x034, 0x0000404A,
+ 0x034, 0x00003047,
+ 0x034, 0x0000200A,
+ 0x034, 0x00001007,
+ 0x034, 0x00000004,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A0B3,
+ 0x034, 0x000090B0,
+ 0x034, 0x00008070,
+ 0x034, 0x0000706D,
+ 0x034, 0x0000604D,
+ 0x034, 0x0000504A,
+ 0x034, 0x00004047,
+ 0x034, 0x00003044,
+ 0x034, 0x00002007,
+ 0x034, 0x00001004,
+ 0x034, 0x00000001,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0000AFF7,
+ 0x034, 0x00009DF7,
+ 0x034, 0x00008DF4,
+ 0x034, 0x00007DF1,
+ 0x034, 0x00006DEE,
+ 0x034, 0x00005DEB,
+ 0x034, 0x00004DE8,
+ 0x034, 0x000038CC,
+ 0x034, 0x000028C9,
+ 0x034, 0x000018C6,
+ 0x034, 0x000008C3,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x035, 0x000001C5,
+ 0x035, 0x000081C5,
+ 0x035, 0x000101C5,
+ 0x035, 0x00020174,
+ 0x035, 0x00028174,
+ 0x035, 0x00030174,
+ 0x035, 0x00040185,
+ 0x035, 0x00048185,
+ 0x035, 0x00050185,
+ 0x0EF, 0x00000000,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x035, 0x000001C5,
+ 0x035, 0x000081C5,
+ 0x035, 0x000101C5,
+ 0x035, 0x00020174,
+ 0x035, 0x00028174,
+ 0x035, 0x00030174,
+ 0x035, 0x00040185,
+ 0x035, 0x00048185,
+ 0x035, 0x00050185,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x035, 0x00000188,
+ 0x035, 0x00008147,
+ 0x035, 0x00010147,
+ 0x035, 0x000201D7,
+ 0x035, 0x000281D7,
+ 0x035, 0x000301D7,
+ 0x035, 0x000401D8,
+ 0x035, 0x000481D8,
+ 0x035, 0x000501D8,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x036, 0x00005B8B,
+ 0x036, 0x0000DB8B,
+ 0x036, 0x00015B8B,
+ 0x036, 0x0001DB8B,
+ 0x036, 0x000262DB,
+ 0x036, 0x0002E2DB,
+ 0x036, 0x000362DB,
+ 0x036, 0x0003E2DB,
+ 0x036, 0x0004553B,
+ 0x036, 0x0004D53B,
+ 0x036, 0x0005553B,
+ 0x036, 0x0005D53B,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x036, 0x00005B8B,
+ 0x036, 0x0000DB8B,
+ 0x036, 0x00015B8B,
+ 0x036, 0x0001DB8B,
+ 0x036, 0x000262DB,
+ 0x036, 0x0002E2DB,
+ 0x036, 0x000362DB,
+ 0x036, 0x0003E2DB,
+ 0x036, 0x0004553B,
+ 0x036, 0x0004D53B,
+ 0x036, 0x0005553B,
+ 0x036, 0x0005D53B,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x036, 0x00084EB4,
+ 0x036, 0x0008CC35,
+ 0x036, 0x00094C35,
+ 0x036, 0x0009CC35,
+ 0x036, 0x000A4C35,
+ 0x036, 0x000ACC35,
+ 0x036, 0x000B4C35,
+ 0x036, 0x000BCC35,
+ 0x036, 0x000C4C34,
+ 0x036, 0x000CCC35,
+ 0x036, 0x000D4C35,
+ 0x036, 0x000DCC35,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00000008,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000002DC,
+ 0x03C, 0x00000524,
+ 0x03C, 0x00000902,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000002DC,
+ 0x03C, 0x00000524,
+ 0x03C, 0x00000902,
+ 0xA0000000, 0x00000000,
+ 0x03C, 0x000002A8,
+ 0x03C, 0x000005A2,
+ 0x03C, 0x00000880,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000002,
+ 0x0DF, 0x00000080,
+ 0x80000008, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000EAC43,
+ 0x062, 0x00038F47,
+ 0x063, 0x00031157,
+ 0x064, 0x0001C4AC,
+ 0x065, 0x000931D1,
+ 0x90000008, 0x05000000, 0x40000000, 0x00000000,
+ 0x061, 0x000EAC43,
+ 0x062, 0x00038F47,
+ 0x063, 0x00031157,
+ 0x064, 0x0001C4AC,
+ 0x065, 0x000931D2,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000EAC43,
+ 0x062, 0x00038F47,
+ 0x063, 0x00031157,
+ 0x064, 0x0001C4AC,
+ 0x065, 0x000931D1,
+ 0xA0000000, 0x00000000,
+ 0x061, 0x000E5D53,
+ 0x062, 0x00038FCD,
+ 0x063, 0x000114EB,
+ 0x064, 0x000196AC,
+ 0x065, 0x000911D7,
+ 0xB0000000, 0x00000000,
+ 0x008, 0x00008400,
+};
+
+RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_b, B);
+
+static const struct rtw_txpwr_lmt_cfg_pair rtw8812a_txpwr_lmt[] = {
+ { 0, 0, 0, 0, 1, 36, },
+ { 2, 0, 0, 0, 1, 32, },
+ { 1, 0, 0, 0, 1, 32, },
+ { 0, 0, 0, 0, 2, 36, },
+ { 2, 0, 0, 0, 2, 32, },
+ { 1, 0, 0, 0, 2, 32, },
+ { 0, 0, 0, 0, 3, 36, },
+ { 2, 0, 0, 0, 3, 32, },
+ { 1, 0, 0, 0, 3, 32, },
+ { 0, 0, 0, 0, 4, 36, },
+ { 2, 0, 0, 0, 4, 32, },
+ { 1, 0, 0, 0, 4, 32, },
+ { 0, 0, 0, 0, 5, 36, },
+ { 2, 0, 0, 0, 5, 32, },
+ { 1, 0, 0, 0, 5, 32, },
+ { 0, 0, 0, 0, 6, 36, },
+ { 2, 0, 0, 0, 6, 32, },
+ { 1, 0, 0, 0, 6, 32, },
+ { 0, 0, 0, 0, 7, 36, },
+ { 2, 0, 0, 0, 7, 32, },
+ { 1, 0, 0, 0, 7, 32, },
+ { 0, 0, 0, 0, 8, 36, },
+ { 2, 0, 0, 0, 8, 32, },
+ { 1, 0, 0, 0, 8, 32, },
+ { 0, 0, 0, 0, 9, 36, },
+ { 2, 0, 0, 0, 9, 32, },
+ { 1, 0, 0, 0, 9, 32, },
+ { 0, 0, 0, 0, 10, 36, },
+ { 2, 0, 0, 0, 10, 32, },
+ { 1, 0, 0, 0, 10, 32, },
+ { 0, 0, 0, 0, 11, 36, },
+ { 2, 0, 0, 0, 11, 32, },
+ { 1, 0, 0, 0, 11, 32, },
+ { 0, 0, 0, 0, 12, 63, },
+ { 2, 0, 0, 0, 12, 32, },
+ { 1, 0, 0, 0, 12, 32, },
+ { 0, 0, 0, 0, 13, 63, },
+ { 2, 0, 0, 0, 13, 32, },
+ { 1, 0, 0, 0, 13, 32, },
+ { 0, 0, 0, 0, 14, 63, },
+ { 2, 0, 0, 0, 14, 63, },
+ { 1, 0, 0, 0, 14, 32, },
+ { 0, 0, 0, 1, 1, 34, },
+ { 2, 0, 0, 1, 1, 32, },
+ { 1, 0, 0, 1, 1, 32, },
+ { 0, 0, 0, 1, 2, 36, },
+ { 2, 0, 0, 1, 2, 32, },
+ { 1, 0, 0, 1, 2, 32, },
+ { 0, 0, 0, 1, 3, 36, },
+ { 2, 0, 0, 1, 3, 32, },
+ { 1, 0, 0, 1, 3, 32, },
+ { 0, 0, 0, 1, 4, 36, },
+ { 2, 0, 0, 1, 4, 32, },
+ { 1, 0, 0, 1, 4, 32, },
+ { 0, 0, 0, 1, 5, 36, },
+ { 2, 0, 0, 1, 5, 32, },
+ { 1, 0, 0, 1, 5, 32, },
+ { 0, 0, 0, 1, 6, 36, },
+ { 2, 0, 0, 1, 6, 32, },
+ { 1, 0, 0, 1, 6, 32, },
+ { 0, 0, 0, 1, 7, 36, },
+ { 2, 0, 0, 1, 7, 32, },
+ { 1, 0, 0, 1, 7, 32, },
+ { 0, 0, 0, 1, 8, 36, },
+ { 2, 0, 0, 1, 8, 32, },
+ { 1, 0, 0, 1, 8, 32, },
+ { 0, 0, 0, 1, 9, 36, },
+ { 2, 0, 0, 1, 9, 32, },
+ { 1, 0, 0, 1, 9, 32, },
+ { 0, 0, 0, 1, 10, 36, },
+ { 2, 0, 0, 1, 10, 32, },
+ { 1, 0, 0, 1, 10, 32, },
+ { 0, 0, 0, 1, 11, 32, },
+ { 2, 0, 0, 1, 11, 32, },
+ { 1, 0, 0, 1, 11, 32, },
+ { 0, 0, 0, 1, 12, 63, },
+ { 2, 0, 0, 1, 12, 32, },
+ { 1, 0, 0, 1, 12, 32, },
+ { 0, 0, 0, 1, 13, 63, },
+ { 2, 0, 0, 1, 13, 32, },
+ { 1, 0, 0, 1, 13, 32, },
+ { 0, 0, 0, 1, 14, 63, },
+ { 2, 0, 0, 1, 14, 63, },
+ { 1, 0, 0, 1, 14, 63, },
+ { 0, 0, 0, 2, 1, 34, },
+ { 2, 0, 0, 2, 1, 32, },
+ { 1, 0, 0, 2, 1, 32, },
+ { 0, 0, 0, 2, 2, 36, },
+ { 2, 0, 0, 2, 2, 32, },
+ { 1, 0, 0, 2, 2, 32, },
+ { 0, 0, 0, 2, 3, 36, },
+ { 2, 0, 0, 2, 3, 32, },
+ { 1, 0, 0, 2, 3, 32, },
+ { 0, 0, 0, 2, 4, 36, },
+ { 2, 0, 0, 2, 4, 32, },
+ { 1, 0, 0, 2, 4, 32, },
+ { 0, 0, 0, 2, 5, 36, },
+ { 2, 0, 0, 2, 5, 32, },
+ { 1, 0, 0, 2, 5, 32, },
+ { 0, 0, 0, 2, 6, 36, },
+ { 2, 0, 0, 2, 6, 32, },
+ { 1, 0, 0, 2, 6, 32, },
+ { 0, 0, 0, 2, 7, 36, },
+ { 2, 0, 0, 2, 7, 32, },
+ { 1, 0, 0, 2, 7, 32, },
+ { 0, 0, 0, 2, 8, 36, },
+ { 2, 0, 0, 2, 8, 32, },
+ { 1, 0, 0, 2, 8, 32, },
+ { 0, 0, 0, 2, 9, 36, },
+ { 2, 0, 0, 2, 9, 32, },
+ { 1, 0, 0, 2, 9, 32, },
+ { 0, 0, 0, 2, 10, 36, },
+ { 2, 0, 0, 2, 10, 32, },
+ { 1, 0, 0, 2, 10, 32, },
+ { 0, 0, 0, 2, 11, 32, },
+ { 2, 0, 0, 2, 11, 32, },
+ { 1, 0, 0, 2, 11, 32, },
+ { 0, 0, 0, 2, 12, 63, },
+ { 2, 0, 0, 2, 12, 32, },
+ { 1, 0, 0, 2, 12, 32, },
+ { 0, 0, 0, 2, 13, 63, },
+ { 2, 0, 0, 2, 13, 32, },
+ { 1, 0, 0, 2, 13, 32, },
+ { 0, 0, 0, 2, 14, 63, },
+ { 2, 0, 0, 2, 14, 63, },
+ { 1, 0, 0, 2, 14, 63, },
+ { 0, 0, 0, 3, 1, 32, },
+ { 2, 0, 0, 3, 1, 32, },
+ { 1, 0, 0, 3, 1, 32, },
+ { 0, 0, 0, 3, 2, 34, },
+ { 2, 0, 0, 3, 2, 32, },
+ { 1, 0, 0, 3, 2, 32, },
+ { 0, 0, 0, 3, 3, 34, },
+ { 2, 0, 0, 3, 3, 32, },
+ { 1, 0, 0, 3, 3, 32, },
+ { 0, 0, 0, 3, 4, 34, },
+ { 2, 0, 0, 3, 4, 32, },
+ { 1, 0, 0, 3, 4, 32, },
+ { 0, 0, 0, 3, 5, 34, },
+ { 2, 0, 0, 3, 5, 32, },
+ { 1, 0, 0, 3, 5, 32, },
+ { 0, 0, 0, 3, 6, 34, },
+ { 2, 0, 0, 3, 6, 32, },
+ { 1, 0, 0, 3, 6, 32, },
+ { 0, 0, 0, 3, 7, 34, },
+ { 2, 0, 0, 3, 7, 32, },
+ { 1, 0, 0, 3, 7, 32, },
+ { 0, 0, 0, 3, 8, 34, },
+ { 2, 0, 0, 3, 8, 32, },
+ { 1, 0, 0, 3, 8, 32, },
+ { 0, 0, 0, 3, 9, 34, },
+ { 2, 0, 0, 3, 9, 32, },
+ { 1, 0, 0, 3, 9, 32, },
+ { 0, 0, 0, 3, 10, 34, },
+ { 2, 0, 0, 3, 10, 32, },
+ { 1, 0, 0, 3, 10, 32, },
+ { 0, 0, 0, 3, 11, 30, },
+ { 2, 0, 0, 3, 11, 32, },
+ { 1, 0, 0, 3, 11, 32, },
+ { 0, 0, 0, 3, 12, 63, },
+ { 2, 0, 0, 3, 12, 32, },
+ { 1, 0, 0, 3, 12, 32, },
+ { 0, 0, 0, 3, 13, 63, },
+ { 2, 0, 0, 3, 13, 32, },
+ { 1, 0, 0, 3, 13, 32, },
+ { 0, 0, 0, 3, 14, 63, },
+ { 2, 0, 0, 3, 14, 63, },
+ { 1, 0, 0, 3, 14, 63, },
+ { 0, 0, 1, 2, 1, 63, },
+ { 2, 0, 1, 2, 1, 63, },
+ { 1, 0, 1, 2, 1, 63, },
+ { 0, 0, 1, 2, 2, 63, },
+ { 2, 0, 1, 2, 2, 63, },
+ { 1, 0, 1, 2, 2, 63, },
+ { 0, 0, 1, 2, 3, 32, },
+ { 2, 0, 1, 2, 3, 32, },
+ { 1, 0, 1, 2, 3, 32, },
+ { 0, 0, 1, 2, 4, 36, },
+ { 2, 0, 1, 2, 4, 32, },
+ { 1, 0, 1, 2, 4, 32, },
+ { 0, 0, 1, 2, 5, 36, },
+ { 2, 0, 1, 2, 5, 32, },
+ { 1, 0, 1, 2, 5, 32, },
+ { 0, 0, 1, 2, 6, 36, },
+ { 2, 0, 1, 2, 6, 32, },
+ { 1, 0, 1, 2, 6, 32, },
+ { 0, 0, 1, 2, 7, 36, },
+ { 2, 0, 1, 2, 7, 32, },
+ { 1, 0, 1, 2, 7, 32, },
+ { 0, 0, 1, 2, 8, 36, },
+ { 2, 0, 1, 2, 8, 32, },
+ { 1, 0, 1, 2, 8, 32, },
+ { 0, 0, 1, 2, 9, 36, },
+ { 2, 0, 1, 2, 9, 32, },
+ { 1, 0, 1, 2, 9, 32, },
+ { 0, 0, 1, 2, 10, 36, },
+ { 2, 0, 1, 2, 10, 32, },
+ { 1, 0, 1, 2, 10, 32, },
+ { 0, 0, 1, 2, 11, 32, },
+ { 2, 0, 1, 2, 11, 32, },
+ { 1, 0, 1, 2, 11, 32, },
+ { 0, 0, 1, 2, 12, 63, },
+ { 2, 0, 1, 2, 12, 32, },
+ { 1, 0, 1, 2, 12, 32, },
+ { 0, 0, 1, 2, 13, 63, },
+ { 2, 0, 1, 2, 13, 32, },
+ { 1, 0, 1, 2, 13, 32, },
+ { 0, 0, 1, 2, 14, 63, },
+ { 2, 0, 1, 2, 14, 63, },
+ { 1, 0, 1, 2, 14, 63, },
+ { 0, 0, 1, 3, 1, 63, },
+ { 2, 0, 1, 3, 1, 63, },
+ { 1, 0, 1, 3, 1, 63, },
+ { 0, 0, 1, 3, 2, 63, },
+ { 2, 0, 1, 3, 2, 63, },
+ { 1, 0, 1, 3, 2, 63, },
+ { 0, 0, 1, 3, 3, 30, },
+ { 2, 0, 1, 3, 3, 30, },
+ { 1, 0, 1, 3, 3, 30, },
+ { 0, 0, 1, 3, 4, 34, },
+ { 2, 0, 1, 3, 4, 30, },
+ { 1, 0, 1, 3, 4, 30, },
+ { 0, 0, 1, 3, 5, 34, },
+ { 2, 0, 1, 3, 5, 30, },
+ { 1, 0, 1, 3, 5, 30, },
+ { 0, 0, 1, 3, 6, 34, },
+ { 2, 0, 1, 3, 6, 30, },
+ { 1, 0, 1, 3, 6, 30, },
+ { 0, 0, 1, 3, 7, 34, },
+ { 2, 0, 1, 3, 7, 30, },
+ { 1, 0, 1, 3, 7, 30, },
+ { 0, 0, 1, 3, 8, 34, },
+ { 2, 0, 1, 3, 8, 30, },
+ { 1, 0, 1, 3, 8, 30, },
+ { 0, 0, 1, 3, 9, 34, },
+ { 2, 0, 1, 3, 9, 30, },
+ { 1, 0, 1, 3, 9, 30, },
+ { 0, 0, 1, 3, 10, 34, },
+ { 2, 0, 1, 3, 10, 30, },
+ { 1, 0, 1, 3, 10, 30, },
+ { 0, 0, 1, 3, 11, 30, },
+ { 2, 0, 1, 3, 11, 30, },
+ { 1, 0, 1, 3, 11, 30, },
+ { 0, 0, 1, 3, 12, 63, },
+ { 2, 0, 1, 3, 12, 32, },
+ { 1, 0, 1, 3, 12, 32, },
+ { 0, 0, 1, 3, 13, 63, },
+ { 2, 0, 1, 3, 13, 32, },
+ { 1, 0, 1, 3, 13, 32, },
+ { 0, 0, 1, 3, 14, 63, },
+ { 2, 0, 1, 3, 14, 63, },
+ { 1, 0, 1, 3, 14, 63, },
+ { 0, 1, 0, 1, 36, 30, },
+ { 2, 1, 0, 1, 36, 32, },
+ { 1, 1, 0, 1, 36, 32, },
+ { 0, 1, 0, 1, 40, 30, },
+ { 2, 1, 0, 1, 40, 32, },
+ { 1, 1, 0, 1, 40, 32, },
+ { 0, 1, 0, 1, 44, 30, },
+ { 2, 1, 0, 1, 44, 32, },
+ { 1, 1, 0, 1, 44, 32, },
+ { 0, 1, 0, 1, 48, 30, },
+ { 2, 1, 0, 1, 48, 32, },
+ { 1, 1, 0, 1, 48, 32, },
+ { 0, 1, 0, 1, 52, 36, },
+ { 2, 1, 0, 1, 52, 32, },
+ { 1, 1, 0, 1, 52, 32, },
+ { 0, 1, 0, 1, 56, 34, },
+ { 2, 1, 0, 1, 56, 32, },
+ { 1, 1, 0, 1, 56, 32, },
+ { 0, 1, 0, 1, 60, 32, },
+ { 2, 1, 0, 1, 60, 32, },
+ { 1, 1, 0, 1, 60, 32, },
+ { 0, 1, 0, 1, 64, 28, },
+ { 2, 1, 0, 1, 64, 32, },
+ { 1, 1, 0, 1, 64, 32, },
+ { 0, 1, 0, 1, 100, 30, },
+ { 2, 1, 0, 1, 100, 32, },
+ { 1, 1, 0, 1, 100, 32, },
+ { 0, 1, 0, 1, 104, 30, },
+ { 2, 1, 0, 1, 104, 32, },
+ { 1, 1, 0, 1, 104, 32, },
+ { 0, 1, 0, 1, 108, 32, },
+ { 2, 1, 0, 1, 108, 32, },
+ { 1, 1, 0, 1, 108, 32, },
+ { 0, 1, 0, 1, 112, 34, },
+ { 2, 1, 0, 1, 112, 32, },
+ { 1, 1, 0, 1, 112, 32, },
+ { 0, 1, 0, 1, 116, 34, },
+ { 2, 1, 0, 1, 116, 32, },
+ { 1, 1, 0, 1, 116, 32, },
+ { 0, 1, 0, 1, 120, 36, },
+ { 2, 1, 0, 1, 120, 32, },
+ { 1, 1, 0, 1, 120, 32, },
+ { 0, 1, 0, 1, 124, 34, },
+ { 2, 1, 0, 1, 124, 32, },
+ { 1, 1, 0, 1, 124, 32, },
+ { 0, 1, 0, 1, 128, 32, },
+ { 2, 1, 0, 1, 128, 32, },
+ { 1, 1, 0, 1, 128, 32, },
+ { 0, 1, 0, 1, 132, 30, },
+ { 2, 1, 0, 1, 132, 32, },
+ { 1, 1, 0, 1, 132, 32, },
+ { 0, 1, 0, 1, 136, 30, },
+ { 2, 1, 0, 1, 136, 32, },
+ { 1, 1, 0, 1, 136, 32, },
+ { 0, 1, 0, 1, 140, 28, },
+ { 2, 1, 0, 1, 140, 32, },
+ { 1, 1, 0, 1, 140, 32, },
+ { 0, 1, 0, 1, 149, 36, },
+ { 2, 1, 0, 1, 149, 32, },
+ { 1, 1, 0, 1, 149, 63, },
+ { 0, 1, 0, 1, 153, 36, },
+ { 2, 1, 0, 1, 153, 32, },
+ { 1, 1, 0, 1, 153, 63, },
+ { 0, 1, 0, 1, 157, 36, },
+ { 2, 1, 0, 1, 157, 32, },
+ { 1, 1, 0, 1, 157, 63, },
+ { 0, 1, 0, 1, 161, 36, },
+ { 2, 1, 0, 1, 161, 32, },
+ { 1, 1, 0, 1, 161, 63, },
+ { 0, 1, 0, 1, 165, 36, },
+ { 2, 1, 0, 1, 165, 32, },
+ { 1, 1, 0, 1, 165, 63, },
+ { 0, 1, 0, 2, 36, 30, },
+ { 2, 1, 0, 2, 36, 32, },
+ { 1, 1, 0, 2, 36, 32, },
+ { 0, 1, 0, 2, 40, 30, },
+ { 2, 1, 0, 2, 40, 32, },
+ { 1, 1, 0, 2, 40, 32, },
+ { 0, 1, 0, 2, 44, 30, },
+ { 2, 1, 0, 2, 44, 32, },
+ { 1, 1, 0, 2, 44, 32, },
+ { 0, 1, 0, 2, 48, 30, },
+ { 2, 1, 0, 2, 48, 32, },
+ { 1, 1, 0, 2, 48, 32, },
+ { 0, 1, 0, 2, 52, 36, },
+ { 2, 1, 0, 2, 52, 32, },
+ { 1, 1, 0, 2, 52, 32, },
+ { 0, 1, 0, 2, 56, 34, },
+ { 2, 1, 0, 2, 56, 32, },
+ { 1, 1, 0, 2, 56, 32, },
+ { 0, 1, 0, 2, 60, 32, },
+ { 2, 1, 0, 2, 60, 32, },
+ { 1, 1, 0, 2, 60, 32, },
+ { 0, 1, 0, 2, 64, 28, },
+ { 2, 1, 0, 2, 64, 32, },
+ { 1, 1, 0, 2, 64, 32, },
+ { 0, 1, 0, 2, 100, 30, },
+ { 2, 1, 0, 2, 100, 32, },
+ { 1, 1, 0, 2, 100, 32, },
+ { 0, 1, 0, 2, 104, 30, },
+ { 2, 1, 0, 2, 104, 32, },
+ { 1, 1, 0, 2, 104, 32, },
+ { 0, 1, 0, 2, 108, 32, },
+ { 2, 1, 0, 2, 108, 32, },
+ { 1, 1, 0, 2, 108, 32, },
+ { 0, 1, 0, 2, 112, 34, },
+ { 2, 1, 0, 2, 112, 32, },
+ { 1, 1, 0, 2, 112, 32, },
+ { 0, 1, 0, 2, 116, 34, },
+ { 2, 1, 0, 2, 116, 32, },
+ { 1, 1, 0, 2, 116, 32, },
+ { 0, 1, 0, 2, 120, 36, },
+ { 2, 1, 0, 2, 120, 32, },
+ { 1, 1, 0, 2, 120, 32, },
+ { 0, 1, 0, 2, 124, 34, },
+ { 2, 1, 0, 2, 124, 32, },
+ { 1, 1, 0, 2, 124, 32, },
+ { 0, 1, 0, 2, 128, 32, },
+ { 2, 1, 0, 2, 128, 32, },
+ { 1, 1, 0, 2, 128, 32, },
+ { 0, 1, 0, 2, 132, 30, },
+ { 2, 1, 0, 2, 132, 32, },
+ { 1, 1, 0, 2, 132, 32, },
+ { 0, 1, 0, 2, 136, 30, },
+ { 2, 1, 0, 2, 136, 32, },
+ { 1, 1, 0, 2, 136, 32, },
+ { 0, 1, 0, 2, 140, 28, },
+ { 2, 1, 0, 2, 140, 32, },
+ { 1, 1, 0, 2, 140, 32, },
+ { 0, 1, 0, 2, 149, 36, },
+ { 2, 1, 0, 2, 149, 32, },
+ { 1, 1, 0, 2, 149, 63, },
+ { 0, 1, 0, 2, 153, 36, },
+ { 2, 1, 0, 2, 153, 32, },
+ { 1, 1, 0, 2, 153, 63, },
+ { 0, 1, 0, 2, 157, 36, },
+ { 2, 1, 0, 2, 157, 32, },
+ { 1, 1, 0, 2, 157, 63, },
+ { 0, 1, 0, 2, 161, 36, },
+ { 2, 1, 0, 2, 161, 32, },
+ { 1, 1, 0, 2, 161, 63, },
+ { 0, 1, 0, 2, 165, 36, },
+ { 2, 1, 0, 2, 165, 32, },
+ { 1, 1, 0, 2, 165, 63, },
+ { 0, 1, 0, 3, 36, 28, },
+ { 2, 1, 0, 3, 36, 30, },
+ { 1, 1, 0, 3, 36, 30, },
+ { 0, 1, 0, 3, 40, 28, },
+ { 2, 1, 0, 3, 40, 30, },
+ { 1, 1, 0, 3, 40, 30, },
+ { 0, 1, 0, 3, 44, 28, },
+ { 2, 1, 0, 3, 44, 30, },
+ { 1, 1, 0, 3, 44, 30, },
+ { 0, 1, 0, 3, 48, 28, },
+ { 2, 1, 0, 3, 48, 30, },
+ { 1, 1, 0, 3, 48, 30, },
+ { 0, 1, 0, 3, 52, 34, },
+ { 2, 1, 0, 3, 52, 30, },
+ { 1, 1, 0, 3, 52, 30, },
+ { 0, 1, 0, 3, 56, 32, },
+ { 2, 1, 0, 3, 56, 30, },
+ { 1, 1, 0, 3, 56, 30, },
+ { 0, 1, 0, 3, 60, 30, },
+ { 2, 1, 0, 3, 60, 30, },
+ { 1, 1, 0, 3, 60, 30, },
+ { 0, 1, 0, 3, 64, 26, },
+ { 2, 1, 0, 3, 64, 30, },
+ { 1, 1, 0, 3, 64, 30, },
+ { 0, 1, 0, 3, 100, 28, },
+ { 2, 1, 0, 3, 100, 30, },
+ { 1, 1, 0, 3, 100, 30, },
+ { 0, 1, 0, 3, 104, 28, },
+ { 2, 1, 0, 3, 104, 30, },
+ { 1, 1, 0, 3, 104, 30, },
+ { 0, 1, 0, 3, 108, 30, },
+ { 2, 1, 0, 3, 108, 30, },
+ { 1, 1, 0, 3, 108, 30, },
+ { 0, 1, 0, 3, 112, 32, },
+ { 2, 1, 0, 3, 112, 30, },
+ { 1, 1, 0, 3, 112, 30, },
+ { 0, 1, 0, 3, 116, 32, },
+ { 2, 1, 0, 3, 116, 30, },
+ { 1, 1, 0, 3, 116, 30, },
+ { 0, 1, 0, 3, 120, 34, },
+ { 2, 1, 0, 3, 120, 30, },
+ { 1, 1, 0, 3, 120, 30, },
+ { 0, 1, 0, 3, 124, 32, },
+ { 2, 1, 0, 3, 124, 30, },
+ { 1, 1, 0, 3, 124, 30, },
+ { 0, 1, 0, 3, 128, 30, },
+ { 2, 1, 0, 3, 128, 30, },
+ { 1, 1, 0, 3, 128, 30, },
+ { 0, 1, 0, 3, 132, 28, },
+ { 2, 1, 0, 3, 132, 30, },
+ { 1, 1, 0, 3, 132, 30, },
+ { 0, 1, 0, 3, 136, 28, },
+ { 2, 1, 0, 3, 136, 30, },
+ { 1, 1, 0, 3, 136, 30, },
+ { 0, 1, 0, 3, 140, 26, },
+ { 2, 1, 0, 3, 140, 30, },
+ { 1, 1, 0, 3, 140, 30, },
+ { 0, 1, 0, 3, 149, 34, },
+ { 2, 1, 0, 3, 149, 30, },
+ { 1, 1, 0, 3, 149, 63, },
+ { 0, 1, 0, 3, 153, 34, },
+ { 2, 1, 0, 3, 153, 30, },
+ { 1, 1, 0, 3, 153, 63, },
+ { 0, 1, 0, 3, 157, 34, },
+ { 2, 1, 0, 3, 157, 30, },
+ { 1, 1, 0, 3, 157, 63, },
+ { 0, 1, 0, 3, 161, 34, },
+ { 2, 1, 0, 3, 161, 30, },
+ { 1, 1, 0, 3, 161, 63, },
+ { 0, 1, 0, 3, 165, 34, },
+ { 2, 1, 0, 3, 165, 30, },
+ { 1, 1, 0, 3, 165, 63, },
+ { 0, 1, 1, 2, 38, 30, },
+ { 2, 1, 1, 2, 38, 32, },
+ { 1, 1, 1, 2, 38, 32, },
+ { 0, 1, 1, 2, 46, 30, },
+ { 2, 1, 1, 2, 46, 32, },
+ { 1, 1, 1, 2, 46, 32, },
+ { 0, 1, 1, 2, 54, 32, },
+ { 2, 1, 1, 2, 54, 32, },
+ { 1, 1, 1, 2, 54, 32, },
+ { 0, 1, 1, 2, 62, 32, },
+ { 2, 1, 1, 2, 62, 32, },
+ { 1, 1, 1, 2, 62, 32, },
+ { 0, 1, 1, 2, 102, 28, },
+ { 2, 1, 1, 2, 102, 32, },
+ { 1, 1, 1, 2, 102, 32, },
+ { 0, 1, 1, 2, 110, 32, },
+ { 2, 1, 1, 2, 110, 32, },
+ { 1, 1, 1, 2, 110, 32, },
+ { 0, 1, 1, 2, 118, 36, },
+ { 2, 1, 1, 2, 118, 32, },
+ { 1, 1, 1, 2, 118, 32, },
+ { 0, 1, 1, 2, 126, 34, },
+ { 2, 1, 1, 2, 126, 32, },
+ { 1, 1, 1, 2, 126, 32, },
+ { 0, 1, 1, 2, 134, 32, },
+ { 2, 1, 1, 2, 134, 32, },
+ { 1, 1, 1, 2, 134, 32, },
+ { 0, 1, 1, 2, 151, 36, },
+ { 2, 1, 1, 2, 151, 32, },
+ { 1, 1, 1, 2, 151, 63, },
+ { 0, 1, 1, 2, 159, 36, },
+ { 2, 1, 1, 2, 159, 32, },
+ { 1, 1, 1, 2, 159, 63, },
+ { 0, 1, 1, 3, 38, 28, },
+ { 2, 1, 1, 3, 38, 30, },
+ { 1, 1, 1, 3, 38, 30, },
+ { 0, 1, 1, 3, 46, 28, },
+ { 2, 1, 1, 3, 46, 30, },
+ { 1, 1, 1, 3, 46, 30, },
+ { 0, 1, 1, 3, 54, 30, },
+ { 2, 1, 1, 3, 54, 30, },
+ { 1, 1, 1, 3, 54, 30, },
+ { 0, 1, 1, 3, 62, 30, },
+ { 2, 1, 1, 3, 62, 30, },
+ { 1, 1, 1, 3, 62, 30, },
+ { 0, 1, 1, 3, 102, 26, },
+ { 2, 1, 1, 3, 102, 30, },
+ { 1, 1, 1, 3, 102, 30, },
+ { 0, 1, 1, 3, 110, 30, },
+ { 2, 1, 1, 3, 110, 30, },
+ { 1, 1, 1, 3, 110, 30, },
+ { 0, 1, 1, 3, 118, 34, },
+ { 2, 1, 1, 3, 118, 30, },
+ { 1, 1, 1, 3, 118, 30, },
+ { 0, 1, 1, 3, 126, 32, },
+ { 2, 1, 1, 3, 126, 30, },
+ { 1, 1, 1, 3, 126, 30, },
+ { 0, 1, 1, 3, 134, 30, },
+ { 2, 1, 1, 3, 134, 30, },
+ { 1, 1, 1, 3, 134, 30, },
+ { 0, 1, 1, 3, 151, 34, },
+ { 2, 1, 1, 3, 151, 30, },
+ { 1, 1, 1, 3, 151, 63, },
+ { 0, 1, 1, 3, 159, 34, },
+ { 2, 1, 1, 3, 159, 30, },
+ { 1, 1, 1, 3, 159, 63, },
+ { 0, 1, 2, 4, 42, 30, },
+ { 2, 1, 2, 4, 42, 32, },
+ { 1, 1, 2, 4, 42, 32, },
+ { 0, 1, 2, 4, 58, 28, },
+ { 2, 1, 2, 4, 58, 32, },
+ { 1, 1, 2, 4, 58, 32, },
+ { 0, 1, 2, 4, 106, 30, },
+ { 2, 1, 2, 4, 106, 32, },
+ { 1, 1, 2, 4, 106, 32, },
+ { 0, 1, 2, 4, 122, 34, },
+ { 2, 1, 2, 4, 122, 32, },
+ { 1, 1, 2, 4, 122, 32, },
+ { 0, 1, 2, 4, 155, 36, },
+ { 2, 1, 2, 4, 155, 32, },
+ { 1, 1, 2, 4, 155, 63, },
+ { 0, 1, 2, 5, 42, 28, },
+ { 2, 1, 2, 5, 42, 30, },
+ { 1, 1, 2, 5, 42, 30, },
+ { 0, 1, 2, 5, 58, 26, },
+ { 2, 1, 2, 5, 58, 30, },
+ { 1, 1, 2, 5, 58, 30, },
+ { 0, 1, 2, 5, 106, 28, },
+ { 2, 1, 2, 5, 106, 30, },
+ { 1, 1, 2, 5, 106, 30, },
+ { 0, 1, 2, 5, 122, 32, },
+ { 2, 1, 2, 5, 122, 30, },
+ { 1, 1, 2, 5, 122, 30, },
+ { 0, 1, 2, 5, 155, 34, },
+ { 2, 1, 2, 5, 155, 30, },
+ { 1, 1, 2, 5, 155, 63, },
+};
+
+RTW_DECL_TABLE_TXPWR_LMT(rtw8812a_txpwr_lmt);
+
+static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8812a[] = {
+ {0x0012,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0014,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x80, 0},
+ {0x0015,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x01, 0},
+ {0x0023,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x10, 0},
+ {0x0046,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x00},
+ {0x0043,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x00},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), 0},
+ {0x0003,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
+ {0x0301,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0x0024,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x0028,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8812a[] = {
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), 0},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(0), 0},
+ {0x0024,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0028,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_lps_8812a[] = {
+ {0x0301,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0xFF},
+ {0x0522,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x7F},
+ {0x05F8,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x05F9,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x05FA,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x05FB,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x0c00,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x04},
+ {0x0e00,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x04},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0100,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x03},
+ {0x0101,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0553,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8812a[] = {
+ {0x0c00,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x04},
+ {0x0e00,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x04},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0007,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x2A},
+ {0x0008,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x02, 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(1), 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8812a[] = {
+ {0x0003,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), 0},
+ {0x0080,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x05},
+ {0x0042,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xF0, 0xcc},
+ {0x0042,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xF0, 0xEC},
+ {0x0043,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x07},
+ {0x0045,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x00},
+ {0x0046,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0xff},
+ {0x0047,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0x0014,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x80, BIT(7)},
+ {0x0015,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x01, BIT(0)},
+ {0x0012,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x01, 0},
+ {0x0023,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x10, BIT(4)},
+ {0x0008,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0x02, 0},
+ {0x0007,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x20},
+ {0x001f,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0076,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[] = {
+ trans_carddis_to_cardemu_8812a,
+ trans_cardemu_to_act_8812a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[] = {
+ trans_act_to_lps_8812a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[] = {
+ trans_act_to_cardemu_8812a,
+ trans_cardemu_to_carddis_8812a,
+ NULL
+};
+
+static const u8 rtw8812a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 14, 14, 14, 14, 14},
+ {0, 1, 1, 2, 2, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 14, 14, 14, 14, 14},
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12, 13,
+ 13, 14, 14, 15, 16, 16, 16, 16, 16},
+};
+
+static const u8 rtw8812a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+};
+
+static const u8 rtw8812a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 15, 15, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 15, 15, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 15, 15, 15, 15, 15},
+};
+
+static const u8 rtw8812a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+};
+
+static const u8 rtw8812a_pwrtrk_2gb_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11
+};
+
+static const u8 rtw8812a_pwrtrk_2gb_p[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+static const u8 rtw8812a_pwrtrk_2ga_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10
+};
+
+static const u8 rtw8812a_pwrtrk_2ga_p[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+static const u8 rtw8812a_pwrtrk_2g_cck_b_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11
+};
+
+static const u8 rtw8812a_pwrtrk_2g_cck_b_p[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+static const u8 rtw8812a_pwrtrk_2g_cck_a_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10
+};
+
+static const u8 rtw8812a_pwrtrk_2g_cck_a_p[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl = {
+ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_5gb_n[0],
+ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_5gb_n[1],
+ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_5gb_n[2],
+ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_5gb_p[0],
+ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_5gb_p[1],
+ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_5gb_p[2],
+ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_5ga_n[0],
+ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_5ga_n[1],
+ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_5ga_n[2],
+ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_5ga_p[0],
+ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_5ga_p[1],
+ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_5ga_p[2],
+ .pwrtrk_2gb_n = rtw8812a_pwrtrk_2gb_n,
+ .pwrtrk_2gb_p = rtw8812a_pwrtrk_2gb_p,
+ .pwrtrk_2ga_n = rtw8812a_pwrtrk_2ga_n,
+ .pwrtrk_2ga_p = rtw8812a_pwrtrk_2ga_p,
+ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_2g_cck_b_n,
+ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_2g_cck_b_p,
+ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_2g_cck_a_n,
+ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_2g_cck_a_p,
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_5gb_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13,
+ 13, 14, 15, 16, 16, 17, 17, 18, 18},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11,
+ 12, 14, 13, 13, 14, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 14, 15, 15, 16, 16},
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_5gb_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_5ga_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
+ 13, 14, 15, 16, 16, 17, 17, 18, 18},
+ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 13, 13, 14, 15, 16, 16, 17, 17},
+ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13,
+ 13, 14, 14, 15, 15, 16, 17, 18, 18},
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_5ga_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11},
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2gb_n[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7,
+ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2gb_p[] = {
+ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2ga_n[] = {
+ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2ga_p[] = {
+ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_n[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7,
+ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_p[] = {
+ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_n[] = {
+ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15
+};
+
+static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_p[] = {
+ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11
+};
+
+const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl = {
+ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_rfe3_5gb_n[0],
+ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_rfe3_5gb_n[1],
+ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_rfe3_5gb_n[2],
+ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_rfe3_5gb_p[0],
+ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_rfe3_5gb_p[1],
+ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_rfe3_5gb_p[2],
+ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_rfe3_5ga_n[0],
+ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_rfe3_5ga_n[1],
+ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_rfe3_5ga_n[2],
+ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_rfe3_5ga_p[0],
+ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_rfe3_5ga_p[1],
+ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_rfe3_5ga_p[2],
+ .pwrtrk_2gb_n = rtw8812a_pwrtrk_rfe3_2gb_n,
+ .pwrtrk_2gb_p = rtw8812a_pwrtrk_rfe3_2gb_p,
+ .pwrtrk_2ga_n = rtw8812a_pwrtrk_rfe3_2ga_n,
+ .pwrtrk_2ga_p = rtw8812a_pwrtrk_rfe3_2ga_p,
+ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_rfe3_2g_cck_b_n,
+ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_rfe3_2g_cck_b_p,
+ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_rfe3_2g_cck_a_n,
+ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_rfe3_2g_cck_a_p,
+};
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h
new file mode 100644
index 000000000000..f7ab5e4cf059
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW8812A_TABLE_H__
+#define __RTW8812A_TABLE_H__
+
+extern const struct rtw_table rtw8812a_mac_tbl;
+extern const struct rtw_table rtw8812a_agc_tbl;
+extern const struct rtw_table rtw8812a_agc_diff_lb_tbl;
+extern const struct rtw_table rtw8812a_agc_diff_hb_tbl;
+extern const struct rtw_table rtw8812a_bb_tbl;
+extern const struct rtw_table rtw8812a_bb_pg_tbl;
+extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl;
+extern const struct rtw_table rtw8812a_rf_a_tbl;
+extern const struct rtw_table rtw8812a_rf_b_tbl;
+extern const struct rtw_table rtw8812a_txpwr_lmt_tbl;
+
+extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[];
+extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[];
+extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[];
+
+extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl;
+extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812au.c b/drivers/net/wireless/realtek/rtw88/rtw8812au.c
new file mode 100644
index 000000000000..4da69590a423
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "main.h"
+#include "rtw8812a.h"
+#include "usb.h"
+
+static const struct usb_device_id rtw_8812au_id_table[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) },
+ {},
+};
+MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table);
+
+static struct usb_driver rtw_8812au_driver = {
+ .name = "rtw_8812au",
+ .id_table = rtw_8812au_id_table,
+ .probe = rtw_usb_probe,
+ .disconnect = rtw_usb_disconnect,
+};
+module_usb_driver(rtw_8812au_driver);
+
+MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
new file mode 100644
index 000000000000..db242c9ad68f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
@@ -0,0 +1,1197 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "main.h"
+#include "coex.h"
+#include "phy.h"
+#include "reg.h"
+#include "rtw88xxa.h"
+#include "rtw8821a.h"
+#include "rtw8821a_table.h"
+#include "tx.h"
+
+static void rtw8821a_power_off(struct rtw_dev *rtwdev)
+{
+ rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a);
+}
+
+static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx)
+{
+ static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38};
+ s8 rx_pwr_all = 0;
+ s8 lna_gain;
+
+ switch (lna_idx) {
+ case 5:
+ case 4:
+ case 2:
+ case 1:
+ case 0:
+ lna_gain = lna_gain_table[lna_idx];
+ rx_pwr_all = lna_gain - 2 * vga_idx;
+ break;
+ default:
+ break;
+ }
+
+ return rx_pwr_all;
+}
+
+static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat,
+ rtw8821a_cck_rx_pwr);
+}
+
+static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
+{
+}
+
+#define CAL_NUM_8821A 3
+#define MACBB_REG_NUM_8821A 8
+#define AFE_REG_NUM_8821A 4
+#define RF_REG_NUM_8821A 3
+
+static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup,
+ const u32 *backup_rf_reg, u32 rf_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* Save RF Parameters */
+ for (i = 0; i < rf_num; i++)
+ rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A,
+ backup_rf_reg[i], MASKDWORD);
+}
+
+static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev,
+ const u32 *backup_rf_reg,
+ u32 *RF_backup, u32 rf_reg_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ for (i = 0; i < rf_reg_num; i++)
+ rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i],
+ RFREG_MASK, RF_backup[i]);
+}
+
+static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
+ const u32 *backup_afe_reg, u32 afe_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* Reload AFE Parameters */
+ for (i = 0; i < afe_num; i++)
+ rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0);
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0);
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0);
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);
+ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
+ rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000);
+ rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000);
+ rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x0);
+}
+
+static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev,
+ unsigned int rx_x, unsigned int rx_y)
+{
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x000003ff, rx_x >> 1);
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x03ff0000, (rx_y >> 1) & 0x3ff);
+}
+
+static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev,
+ unsigned int tx_x, unsigned int tx_y)
+{
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
+ rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000);
+ rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000);
+ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y);
+ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x);
+}
+
+static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal,
+ bool *tx0iqkok,
+ int tx_x0[CAL_NUM_8821A],
+ int tx_y0[CAL_NUM_8821A])
+{
+ u32 cal_retry, delay_count, iqk_ready, tx_fail;
+ int tx_dt[3], vdf_y[3], vdf_x[3];
+ int k;
+
+ for (k = 0; k < 3; k++) {
+ switch (k) {
+ case 0:
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE,
+ 0x18008c38);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38);
+ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0);
+ break;
+ case 1:
+ rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE,
+ BIT(28), 0x0);
+ rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE,
+ BIT(28), 0x0);
+ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0);
+ break;
+ case 2:
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "vdf_y[1] = %x vdf_y[0] = %x\n",
+ vdf_y[1] >> 21 & 0x00007ff,
+ vdf_y[0] >> 21 & 0x00007ff);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "vdf_x[1] = %x vdf_x[0] = %x\n",
+ vdf_x[1] >> 21 & 0x00007ff,
+ vdf_x[0] >> 21 & 0x00007ff);
+
+ tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20);
+ tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708;
+ tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0));
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE,
+ 0x18008c20);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20);
+ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000,
+ tx_dt[cal] & 0x00003fff);
+ break;
+ }
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+
+ for (cal_retry = 0; cal_retry < 10; cal_retry++) {
+ /* one shot */
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
+
+ mdelay(10);
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ for (delay_count = 0; delay_count < 20; delay_count++) {
+ iqk_ready = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ BIT(10));
+
+ /* Originally: if (~iqk_ready || delay_count > 20)
+ * that looks like a typo so make it more explicit
+ */
+ iqk_ready = true;
+
+ if (iqk_ready)
+ break;
+
+ mdelay(1);
+ }
+
+ if (delay_count < 20) {
+ /* ============TXIQK Check============== */
+ tx_fail = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ BIT(12));
+
+ /* Originally: if (~tx_fail) {
+ * It looks like a typo, so make it more explicit.
+ */
+ tx_fail = false;
+
+ if (!tx_fail) {
+ rtw_write32(rtwdev, REG_RFECTL_A,
+ 0x02000000);
+ vdf_x[k] = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ 0x07ff0000);
+ vdf_x[k] <<= 21;
+
+ rtw_write32(rtwdev, REG_RFECTL_A,
+ 0x04000000);
+ vdf_y[k] = rtw_read32_mask(rtwdev,
+ REG_IQKA_END,
+ 0x07ff0000);
+ vdf_y[k] <<= 21;
+
+ *tx0iqkok = true;
+ break;
+ }
+
+ rtw_write32_mask(rtwdev, REG_IQC_Y,
+ 0x000007ff, 0x0);
+ rtw_write32_mask(rtwdev, REG_IQC_X,
+ 0x000007ff, 0x200);
+ }
+
+ *tx0iqkok = false;
+ }
+ }
+
+ if (k == 3) {
+ tx_x0[cal] = vdf_x[k - 1];
+ tx_y0[cal] = vdf_y[k - 1];
+ }
+}
+
+static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal,
+ bool *tx0iqkok,
+ int tx_x0[CAL_NUM_8821A],
+ int tx_y0[CAL_NUM_8821A])
+{
+ u32 cal_retry, delay_count, iqk_ready, tx_fail;
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+
+ for (cal_retry = 0; cal_retry < 10; cal_retry++) {
+ /* one shot */
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
+
+ mdelay(10);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ for (delay_count = 0; delay_count < 20; delay_count++) {
+ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10));
+
+ /* Originally: if (~iqk_ready || delay_count > 20)
+ * that looks like a typo so make it more explicit
+ */
+ iqk_ready = true;
+
+ if (iqk_ready)
+ break;
+
+ mdelay(1);
+ }
+
+ if (delay_count < 20) {
+ /* ============TXIQK Check============== */
+ tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12));
+
+ /* Originally: if (~tx_fail) {
+ * It looks like a typo, so make it more explicit.
+ */
+ tx_fail = false;
+
+ if (!tx_fail) {
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);
+ tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
+ 0x07ff0000);
+ tx_x0[cal] <<= 21;
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
+ tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
+ 0x07ff0000);
+ tx_y0[cal] <<= 21;
+
+ *tx0iqkok = true;
+ break;
+ }
+
+ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0);
+ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200);
+ }
+
+ *tx0iqkok = false;
+ }
+}
+
+static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok,
+ int rx_x0[CAL_NUM_8821A],
+ int rx_y0[CAL_NUM_8821A])
+{
+ u32 cal_retry, delay_count, iqk_ready, rx_fail;
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+
+ for (cal_retry = 0; cal_retry < 10; cal_retry++) {
+ /* one shot */
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
+
+ mdelay(10);
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ for (delay_count = 0; delay_count < 20; delay_count++) {
+ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10));
+
+ /* Originally: if (~iqk_ready || delay_count > 20)
+ * that looks like a typo so make it more explicit
+ */
+ iqk_ready = true;
+
+ if (iqk_ready)
+ break;
+
+ mdelay(1);
+ }
+
+ if (delay_count < 20) {
+ /* ============RXIQK Check============== */
+ rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11));
+ if (!rx_fail) {
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
+ rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
+ 0x07ff0000);
+ rx_x0[cal] <<= 21;
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
+ rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
+ 0x07ff0000);
+ rx_y0[cal] <<= 21;
+
+ *rx0iqkok = true;
+ break;
+ }
+
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x000003ff, 0x200 >> 1);
+ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
+ 0x03ff0000, 0x0 >> 1);
+ }
+
+ *rx0iqkok = false;
+ }
+}
+
+static void rtw8821a_iqk(struct rtw_dev *rtwdev)
+{
+ int tx_average = 0, rx_average = 0, rx_iqk_loop = 0;
+ const struct rtw_efuse *efuse = &rtwdev->efuse;
+ int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0;
+ const struct rtw_hal *hal = &rtwdev->hal;
+ bool tx0iqkok = false, rx0iqkok = false;
+ int rx_x_temp = 0, rx_y_temp = 0;
+ int rx_x0[2][CAL_NUM_8821A];
+ int rx_y0[2][CAL_NUM_8821A];
+ int tx_x0[CAL_NUM_8821A];
+ int tx_y0[CAL_NUM_8821A];
+ bool rx_finish1 = false;
+ bool rx_finish2 = false;
+ bool vdf_enable;
+ u32 cal;
+ int i;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n",
+ hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g);
+
+ vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80;
+
+ for (cal = 0; cal < CAL_NUM_8821A; cal++) {
+ /* path-A LOK */
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* ========path-A AFE all on======== */
+ /* Port 0 DAC/ADC on */
+ rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777);
+ rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777);
+
+ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979);
+
+ /* hardware 3-wire off */
+ rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4);
+
+ /* LOK setting */
+
+ /* 1. DAC/ADC sampling rate (160 MHz) */
+ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7);
+
+ /* 2. LoK RF setting (at BW = 20M) */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
+ 0x20000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
+ 0x0003f);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
+ 0xf3fc3);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK,
+ 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);
+ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
+ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);
+ /* TX (X,Y) */
+ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000);
+ /* RX (X,Y) */
+ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000);
+ /* [0]:AGC_en, [15]:idac_K_Mask */
+ rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ if (efuse->ext_pa_5g)
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ 0x821403f7);
+ else
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ 0x821403f4);
+
+ if (hal->current_band_type == RTW_BAND_5G)
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96);
+ else
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96);
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
+ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
+
+ mdelay(10);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00,
+ rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00));
+
+ if (hal->current_band_width == RTW_CHANNEL_WIDTH_40)
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH,
+ RF18_BW_MASK, 0x1);
+ else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80)
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH,
+ RF18_BW_MASK, 0x0);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ /* 3. TX RF setting */
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
+ 0x20000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
+ 0x0003f);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
+ 0xf3fc3);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
+ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
+ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);
+ /* TX (X,Y) */
+ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000);
+ /* RX (X,Y) */
+ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000);
+ /* [0]:AGC_en, [15]:idac_K_Mask */
+ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ if (efuse->ext_pa_5g)
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ 0x821403f7);
+ else
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ 0x821403e3);
+
+ if (hal->current_band_type == RTW_BAND_5G)
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96);
+ else
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96);
+
+ if (vdf_enable)
+ rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok,
+ tx_x0, tx_y0);
+ else
+ rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok,
+ tx_x0, tx_y0);
+
+ if (!tx0iqkok)
+ break; /* TXK fail, Don't do RXK */
+
+ /* ====== RX IQK ====== */
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+ /* 1. RX RF setting */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
+ 0x30000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
+ 0x0002f);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
+ 0xfffbb);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
+
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,
+ (tx_x0[cal] >> 21) & 0x000007ff);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,
+ (tx_y0[cal] >> 21) & 0x000007ff);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0);
+ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
+ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10);
+ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119);
+
+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
+ rx_iqk_loop = 2; /* for 2% fail; */
+ else
+ rx_iqk_loop = 1;
+
+ for (i = 0; i < rx_iqk_loop; i++) {
+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0)
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */
+ else
+ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00);
+
+ rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok,
+ rx_x0[i], rx_y0[i]);
+ }
+
+ if (tx0iqkok)
+ tx_average++;
+ if (rx0iqkok)
+ rx_average++;
+ }
+
+ /* FillIQK Result */
+
+ if (tx_average == 0)
+ return;
+
+ for (i = 0; i < tx_average; i++)
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n",
+ i, (tx_x0[i] >> 21) & 0x000007ff,
+ i, (tx_y0[i] >> 21) & 0x000007ff);
+
+ if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0,
+ &tx_x, &tx_y, true, true))
+ rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y);
+ else
+ rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0);
+
+ if (rx_average == 0)
+ return;
+
+ for (i = 0; i < rx_average; i++) {
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n",
+ i, (rx_x0[0][i] >> 21) & 0x000007ff,
+ i, (rx_y0[0][i] >> 21) & 0x000007ff);
+
+ if (rx_iqk_loop == 2)
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n",
+ i, (rx_x0[1][i] >> 21) & 0x000007ff,
+ i, (rx_y0[1][i] >> 21) & 0x000007ff);
+ }
+
+ rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0],
+ &rx_x_temp, &rx_y_temp, true, true);
+
+ if (rx_finish1) {
+ rx_x = rx_x_temp;
+ rx_y = rx_y_temp;
+ }
+
+ if (rx_iqk_loop == 2) {
+ rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4,
+ rx_x0[1], rx_y0[1],
+ &rx_x, &rx_y, true, true);
+
+ if (rx_finish1 && rx_finish2) {
+ rx_x = (rx_x + rx_x_temp) / 2;
+ rx_y = (rx_y + rx_y_temp) / 2;
+ }
+ }
+
+ if (rx_finish1 || rx_finish2)
+ rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y);
+ else
+ rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0);
+}
+
+static void rtw8821a_do_iqk(struct rtw_dev *rtwdev)
+{
+ static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = {
+ 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c
+ };
+ static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = {
+ 0xc5c, 0xc60, 0xc64, 0xc68
+ };
+ static const u32 backup_rf_reg[RF_REG_NUM_8821A] = {
+ 0x65, 0x8f, 0x0
+ };
+ u32 macbb_backup[MACBB_REG_NUM_8821A];
+ u32 afe_backup[AFE_REG_NUM_8821A];
+ u32 rfa_backup[RF_REG_NUM_8821A];
+
+ rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8821A);
+ rtw88xxa_iqk_backup_afe(rtwdev, afe_backup,
+ backup_afe_reg, AFE_REG_NUM_8821A);
+ rtw8821a_iqk_backup_rf(rtwdev, rfa_backup,
+ backup_rf_reg, RF_REG_NUM_8821A);
+
+ rtw88xxa_iqk_configure_mac(rtwdev);
+
+ rtw8821a_iqk(rtwdev);
+
+ rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg,
+ rfa_backup, RF_REG_NUM_8821A);
+ rtw8821a_iqk_restore_afe(rtwdev, afe_backup,
+ backup_afe_reg, AFE_REG_NUM_8821A);
+ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8821A);
+}
+
+static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev)
+{
+ rtw8821a_do_iqk(rtwdev);
+}
+
+static void rtw8821a_pwr_track(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ if (!dm_info->pwr_trk_triggered) {
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
+ GENMASK(17, 16), 0x03);
+ dm_info->pwr_trk_triggered = true;
+ return;
+ }
+
+ rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk);
+ dm_info->pwr_trk_triggered = false;
+}
+
+static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ u8 *txdesc)
+{
+ fill_txdesc_checksum_common(txdesc, 16);
+}
+
+static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev)
+{
+ u8 val8;
+
+ /* BT report packet sample rate */
+ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
+
+ val8 = BIT_STATIS_BT_EN;
+ if (rtwdev->efuse.share_ant)
+ val8 |= BIT_R_GRANTALL_WLMASK;
+ rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8);
+
+ /* enable BT counter statistics */
+ rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3);
+
+ /* enable PTA */
+ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
+}
+
+static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type,
+ u8 pos_type)
+{
+ bool share_ant = rtwdev->efuse.share_ant;
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_dm *coex_dm = &coex->dm;
+ u32 phase = coex_dm->cur_ant_pos_type;
+
+ if (!rtwdev->efuse.btcoex)
+ return;
+
+ switch (phase) {
+ case COEX_SET_ANT_POWERON:
+ case COEX_SET_ANT_INIT:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
+
+ rtw_write8(rtwdev, REG_RFE_CTRL8,
+ share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN);
+ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1);
+ break;
+ case COEX_SET_ANT_WONLY:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
+
+ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN);
+ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1);
+ break;
+ case COEX_SET_ANT_2G:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
+
+ rtw_write8(rtwdev, REG_RFE_CTRL8,
+ share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN);
+ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1);
+ break;
+ case COEX_SET_ANT_5G:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
+
+ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN);
+ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000,
+ share_ant ? 0x2 : 0x1);
+ break;
+ case COEX_SET_ANT_WOFF:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
+
+ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN);
+ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000,
+ share_ant ? 0x2 : 0x1);
+ break;
+ default:
+ rtw_warn(rtwdev, "%s: not handling phase %d\n",
+ __func__, phase);
+ break;
+ }
+}
+
+static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
+{
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_rfe *coex_rfe = &coex->rfe;
+
+ coex_rfe->ant_switch_exist = true;
+}
+
+static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
+{
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_dm *coex_dm = &coex->dm;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ bool share_ant = efuse->share_ant;
+
+ if (share_ant)
+ return;
+
+ if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
+ return;
+
+ coex_dm->cur_wl_pwr_lvl = wl_pwr;
+}
+
+static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
+{
+}
+
+static const struct rtw_chip_ops rtw8821a_ops = {
+ .power_on = rtw88xxa_power_on,
+ .power_off = rtw8821a_power_off,
+ .phy_set_param = NULL,
+ .read_efuse = rtw88xxa_read_efuse,
+ .query_phy_status = rtw8821a_query_phy_status,
+ .set_channel = rtw88xxa_set_channel,
+ .mac_init = NULL,
+ .read_rf = rtw88xxa_phy_read_rf,
+ .write_rf = rtw_phy_write_rf_reg_sipi,
+ .set_antenna = NULL,
+ .set_tx_power_index = rtw88xxa_set_tx_power_index,
+ .cfg_ldo25 = rtw8821a_cfg_ldo25,
+ .efuse_grant = rtw88xxa_efuse_grant,
+ .false_alarm_statistics = rtw88xxa_false_alarm_statistics,
+ .phy_calibration = rtw8821a_phy_calibration,
+ .cck_pd_set = rtw88xxa_phy_cck_pd_set,
+ .pwr_track = rtw8821a_pwr_track,
+ .config_bfee = NULL,
+ .set_gid_table = NULL,
+ .cfg_csi_rate = NULL,
+ .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum,
+ .coex_set_init = rtw8821a_coex_cfg_init,
+ .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch,
+ .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix,
+ .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug,
+ .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type,
+ .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power,
+ .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,
+};
+
+static const struct rtw_page_table page_table_8821a[] = {
+ /* hq_num, nq_num, lq_num, exq_num, gapq_num */
+ {0, 0, 0, 0, 0}, /* SDIO */
+ {0, 0, 0, 0, 0}, /* PCI */
+ {8, 0, 0, 0, 1}, /* 2 bulk out endpoints */
+ {8, 0, 8, 0, 1}, /* 3 bulk out endpoints */
+ {8, 0, 8, 4, 1}, /* 4 bulk out endpoints */
+};
+
+static const struct rtw_rqpn rqpn_table_8821a[] = {
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH,
+ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
+
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+};
+
+static const struct rtw_prioq_addrs prioq_addrs_8821a = {
+ .prio[RTW_DMA_MAPPING_EXTRA] = {
+ .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
+ },
+ .prio[RTW_DMA_MAPPING_LOW] = {
+ .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
+ },
+ .prio[RTW_DMA_MAPPING_NORMAL] = {
+ .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
+ },
+ .prio[RTW_DMA_MAPPING_HIGH] = {
+ .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
+ },
+ .wsize = false,
+};
+
+static const struct rtw_hw_reg rtw8821a_dig[] = {
+ [0] = { .addr = REG_RXIGI_A, .mask = 0x7f },
+};
+
+static const struct rtw_rfe_def rtw8821a_rfe_defs[] = {
+ [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl,
+ .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl,
+ .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, },
+};
+
+/* TODO */
+/* rssi in percentage % (dbm = % - 100) */
+static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40};
+static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101};
+
+/* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a
+ * are copied from rtw8821c.c because the 8821au driver's tables are not
+ * compatible with the coex code in rtw88.
+ *
+ * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51,
+ * otherwise the firmware gets confused after pausing the music:
+ * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00]
+ * - 81 means PAN (personal area network) when it should be 4x (A2DP)
+ * The music is not smooth with the PAN algorithm.
+ */
+
+/* Shared-Antenna Coex Table */
+static const struct coex_table_para table_sant_8821a[] = {
+ {0x55555555, 0x55555555}, /* case-0 */
+ {0x55555555, 0x55555555},
+ {0x66555555, 0x66555555},
+ {0xaaaaaaaa, 0xaaaaaaaa},
+ {0x5a5a5a5a, 0x5a5a5a5a},
+ {0xfafafafa, 0xfafafafa}, /* case-5 */
+ {0x6a5a5555, 0xaaaaaaaa},
+ {0x6a5a56aa, 0x6a5a56aa},
+ {0x6a5a5a5a, 0x6a5a5a5a},
+ {0x66555555, 0x5a5a5a5a},
+ {0x66555555, 0x6a5a5a5a}, /* case-10 */
+ {0x66555555, 0xaaaaaaaa},
+ {0x66555555, 0x6a5a5aaa},
+ {0x66555555, 0x6aaa6aaa},
+ {0x66555555, 0x6a5a5aaa},
+ {0x66555555, 0xaaaaaaaa}, /* case-15 */
+ {0xffff55ff, 0xfafafafa},
+ {0xffff55ff, 0x6afa5afa},
+ {0xaaffffaa, 0xfafafafa},
+ {0xaa5555aa, 0x5a5a5a5a},
+ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
+ {0xaa5555aa, 0xaaaaaaaa},
+ {0xffffffff, 0x55555555},
+ {0xffffffff, 0x5a5a5a5a},
+ {0xffffffff, 0x5a5a5a5a},
+ {0xffffffff, 0x5a5a5aaa}, /* case-25 */
+ {0x55555555, 0x5a5a5a5a},
+ {0x55555555, 0xaaaaaaaa},
+ {0x66555555, 0x6a5a6a5a},
+ {0x66556655, 0x66556655},
+ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */
+ {0xffffffff, 0x5aaa5aaa},
+ {0x56555555, 0x5a5a5aaa}
+};
+
+/* Non-Shared-Antenna Coex Table */
+static const struct coex_table_para table_nsant_8821a[] = {
+ {0xffffffff, 0xffffffff}, /* case-100 */
+ {0xffff55ff, 0xfafafafa},
+ {0x66555555, 0x66555555},
+ {0xaaaaaaaa, 0xaaaaaaaa},
+ {0x5a5a5a5a, 0x5a5a5a5a},
+ {0xffffffff, 0xffffffff}, /* case-105 */
+ {0x5afa5afa, 0x5afa5afa},
+ {0x55555555, 0xfafafafa},
+ {0x66555555, 0xfafafafa},
+ {0x66555555, 0x5a5a5a5a},
+ {0x66555555, 0x6a5a5a5a}, /* case-110 */
+ {0x66555555, 0xaaaaaaaa},
+ {0xffff55ff, 0xfafafafa},
+ {0xffff55ff, 0x5afa5afa},
+ {0xffff55ff, 0xaaaaaaaa},
+ {0xffff55ff, 0xffff55ff}, /* case-115 */
+ {0xaaffffaa, 0x5afa5afa},
+ {0xaaffffaa, 0xaaaaaaaa},
+ {0xffffffff, 0xfafafafa},
+ {0xffff55ff, 0xfafafafa},
+ {0xffffffff, 0xaaaaaaaa}, /* case-120 */
+ {0xffff55ff, 0x5afa5afa},
+ {0xffff55ff, 0x5afa5afa},
+ {0x55ff55ff, 0x55ff55ff}
+};
+
+/* Shared-Antenna TDMA */
+static const struct coex_tdma_para tdma_sant_8821a[] = {
+ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
+ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
+ { {0x61, 0x3a, 0x03, 0x11, 0x11} },
+ { {0x61, 0x35, 0x03, 0x11, 0x11} },
+ { {0x61, 0x20, 0x03, 0x11, 0x11} },
+ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */
+ { {0x61, 0x45, 0x03, 0x11, 0x10} },
+ { {0x61, 0x35, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x20, 0x03, 0x11, 0x10} },
+ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
+ { {0x61, 0x08, 0x03, 0x11, 0x15} },
+ { {0x61, 0x08, 0x03, 0x10, 0x14} },
+ { {0x51, 0x08, 0x03, 0x10, 0x54} },
+ { {0x51, 0x08, 0x03, 0x10, 0x55} },
+ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
+ { {0x51, 0x45, 0x03, 0x10, 0x50} },
+ { {0x51, 0x3a, 0x03, 0x11, 0x50} },
+ { {0x51, 0x30, 0x03, 0x10, 0x50} },
+ { {0x51, 0x21, 0x03, 0x10, 0x50} },
+ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
+ { {0x51, 0x4a, 0x03, 0x10, 0x50} },
+ { {0x51, 0x08, 0x03, 0x30, 0x54} },
+ { {0x55, 0x08, 0x03, 0x10, 0x54} },
+ { {0x65, 0x10, 0x03, 0x11, 0x10} },
+ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
+ { {0x51, 0x21, 0x03, 0x10, 0x50} },
+ { {0x61, 0x08, 0x03, 0x11, 0x11} }
+};
+
+/* Non-Shared-Antenna TDMA */
+static const struct coex_tdma_para tdma_nsant_8821a[] = {
+ { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */
+ { {0x61, 0x45, 0x03, 0x11, 0x11} },
+ { {0x61, 0x25, 0x03, 0x11, 0x11} },
+ { {0x61, 0x35, 0x03, 0x11, 0x11} },
+ { {0x61, 0x20, 0x03, 0x11, 0x11} },
+ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
+ { {0x61, 0x45, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x20, 0x03, 0x11, 0x10} },
+ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
+ { {0x61, 0x10, 0x03, 0x11, 0x11} },
+ { {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */
+ { {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */
+ { {0x51, 0x08, 0x03, 0x10, 0x55} },
+ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
+ { {0x51, 0x45, 0x03, 0x10, 0x50} },
+ { {0x51, 0x3a, 0x03, 0x10, 0x50} },
+ { {0x51, 0x30, 0x03, 0x10, 0x50} },
+ { {0x51, 0x21, 0x03, 0x10, 0x50} },
+ { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */
+ { {0x51, 0x10, 0x03, 0x10, 0x50} }
+};
+
+/* TODO */
+static const struct coex_rf_para rf_para_tx_8821a[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 20, false, 7}, /* for WL-CPT */
+ {8, 17, true, 4},
+ {7, 18, true, 4},
+ {6, 19, true, 4},
+ {5, 20, true, 4}
+};
+
+static const struct coex_rf_para rf_para_rx_8821a[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 20, false, 7}, /* for WL-CPT */
+ {3, 24, true, 5},
+ {2, 26, true, 5},
+ {1, 27, true, 5},
+ {0, 28, true, 5}
+};
+
+static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a));
+
+static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} };
+
+static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = {
+ {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0, 0, RTW_REG_DOMAIN_NL},
+ {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
+ {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
+ {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
+ {0, 0, RTW_REG_DOMAIN_NL},
+ {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
+ {0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
+ {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
+ {0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
+ {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A},
+ {0, 0, RTW_REG_DOMAIN_NL},
+ {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
+ {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+};
+
+const struct rtw_chip_info rtw8821a_hw_spec = {
+ .ops = &rtw8821a_ops,
+ .id = RTW_CHIP_TYPE_8821A,
+ .fw_name = "rtw88/rtw8821a_fw.bin",
+ .wlan_cpu = RTW_WCPU_11N,
+ .tx_pkt_desc_sz = 40,
+ .tx_buf_desc_sz = 16,
+ .rx_pkt_desc_sz = 24,
+ .rx_buf_desc_sz = 8,
+ .phy_efuse_size = 512,
+ .log_efuse_size = 512,
+ .ptct_efuse_size = 96 + 1, /* TODO or just 18? */
+ .txff_size = 65536,
+ .rxff_size = 16128,
+ .rsvd_drv_pg_num = 8,
+ .txgi_factor = 1,
+ .is_pwr_by_rate_dec = true,
+ .max_power_index = 0x3f,
+ .csi_buf_pg_num = 0,
+ .band = RTW_BAND_2G | RTW_BAND_5G,
+ .page_size = 256,
+ .dig_min = 0x20,
+ .ht_supported = true,
+ .vht_supported = true,
+ .lps_deep_mode_supported = 0,
+ .sys_func_en = 0xFD,
+ .pwr_on_seq = card_enable_flow_8821a,
+ .pwr_off_seq = card_disable_flow_8821a,
+ .page_table = page_table_8821a,
+ .rqpn_table = rqpn_table_8821a,
+ .prioq_addrs = &prioq_addrs_8821a,
+ .intf_table = NULL,
+ .dig = rtw8821a_dig,
+ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B},
+ .ltecoex_addr = NULL,
+ .mac_tbl = &rtw8821a_mac_tbl,
+ .agc_tbl = &rtw8821a_agc_tbl,
+ .bb_tbl = &rtw8821a_bb_tbl,
+ .rf_tbl = {&rtw8821a_rf_a_tbl},
+ .rfe_defs = rtw8821a_rfe_defs,
+ .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs),
+ .rx_ldpc = false,
+ .hw_feature_report = false,
+ .c2h_ra_report_size = 4,
+ .old_datarate_fb_limit = true,
+ .usb_tx_agg_desc_num = 6,
+ .iqk_threshold = 8,
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
+
+ .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */
+ .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */
+ .scbd_support = false,
+ .new_scbd10_def = false,
+ .ble_hid_profile_support = false,
+ .wl_mimo_ps_support = false,
+ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
+ .bt_rssi_type = COEX_BTRSSI_RATIO,
+ .ant_isolation = 10,
+ .rssi_tolerance = 2,
+ .wl_rssi_step = wl_rssi_step_8821a,
+ .bt_rssi_step = bt_rssi_step_8821a,
+ .table_sant_num = ARRAY_SIZE(table_sant_8821a),
+ .table_sant = table_sant_8821a,
+ .table_nsant_num = ARRAY_SIZE(table_nsant_8821a),
+ .table_nsant = table_nsant_8821a,
+ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a),
+ .tdma_sant = tdma_sant_8821a,
+ .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a),
+ .tdma_nsant = tdma_nsant_8821a,
+ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a),
+ .wl_rf_para_tx = rf_para_tx_8821a,
+ .wl_rf_para_rx = rf_para_rx_8821a,
+ .bt_afh_span_bw20 = 0x20,
+ .bt_afh_span_bw40 = 0x30,
+ .afh_5g_num = ARRAY_SIZE(afh_5g_8821a),
+ .afh_5g = afh_5g_8821a,
+
+ .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a),
+ .coex_info_hw_regs = coex_info_hw_regs_8821a,
+};
+EXPORT_SYMBOL(rtw8821a_hw_spec);
+
+MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin");
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.h b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
new file mode 100644
index 000000000000..1b2e548f7234
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW8821A_H__
+#define __RTW8821A_H__
+
+extern const struct rtw_chip_info rtw8821a_hw_spec;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c
new file mode 100644
index 000000000000..c8fd8e331f69
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c
@@ -0,0 +1,2350 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "main.h"
+#include "phy.h"
+#include "rtw8821a_table.h"
+
+static const u32 rtw8821a_mac[] = {
+ 0x421, 0x0000000F,
+ 0x428, 0x0000000A,
+ 0x429, 0x00000010,
+ 0x430, 0x00000000,
+ 0x431, 0x00000000,
+ 0x432, 0x00000000,
+ 0x433, 0x00000001,
+ 0x434, 0x00000004,
+ 0x435, 0x00000005,
+ 0x436, 0x00000007,
+ 0x437, 0x00000008,
+ 0x43C, 0x00000004,
+ 0x43D, 0x00000005,
+ 0x43E, 0x00000007,
+ 0x43F, 0x00000008,
+ 0x440, 0x0000005D,
+ 0x441, 0x00000001,
+ 0x442, 0x00000000,
+ 0x444, 0x00000010,
+ 0x445, 0x00000000,
+ 0x446, 0x00000000,
+ 0x447, 0x00000000,
+ 0x448, 0x00000000,
+ 0x449, 0x000000F0,
+ 0x44A, 0x0000000F,
+ 0x44B, 0x0000003E,
+ 0x44C, 0x00000010,
+ 0x44D, 0x00000000,
+ 0x44E, 0x00000000,
+ 0x44F, 0x00000000,
+ 0x450, 0x00000000,
+ 0x451, 0x000000F0,
+ 0x452, 0x0000000F,
+ 0x453, 0x00000000,
+ 0x456, 0x0000005E,
+ 0x460, 0x00000066,
+ 0x461, 0x00000066,
+ 0x4C8, 0x0000003F,
+ 0x4C9, 0x000000FF,
+ 0x4CC, 0x000000FF,
+ 0x4CD, 0x000000FF,
+ 0x4CE, 0x00000001,
+ 0x500, 0x00000026,
+ 0x501, 0x000000A2,
+ 0x502, 0x0000002F,
+ 0x503, 0x00000000,
+ 0x504, 0x00000028,
+ 0x505, 0x000000A3,
+ 0x506, 0x0000005E,
+ 0x507, 0x00000000,
+ 0x508, 0x0000002B,
+ 0x509, 0x000000A4,
+ 0x50A, 0x0000005E,
+ 0x50B, 0x00000000,
+ 0x50C, 0x0000004F,
+ 0x50D, 0x000000A4,
+ 0x50E, 0x00000000,
+ 0x50F, 0x00000000,
+ 0x512, 0x0000001C,
+ 0x514, 0x0000000A,
+ 0x516, 0x0000000A,
+ 0x525, 0x0000004F,
+ 0x550, 0x00000010,
+ 0x551, 0x00000010,
+ 0x559, 0x00000002,
+ 0x55C, 0x00000050,
+ 0x55D, 0x000000FF,
+ 0x605, 0x00000030,
+ 0x607, 0x00000007,
+ 0x608, 0x0000000E,
+ 0x609, 0x0000002A,
+ 0x620, 0x000000FF,
+ 0x621, 0x000000FF,
+ 0x622, 0x000000FF,
+ 0x623, 0x000000FF,
+ 0x624, 0x000000FF,
+ 0x625, 0x000000FF,
+ 0x626, 0x000000FF,
+ 0x627, 0x000000FF,
+ 0x638, 0x00000050,
+ 0x63C, 0x0000000A,
+ 0x63D, 0x0000000A,
+ 0x63E, 0x0000000E,
+ 0x63F, 0x0000000E,
+ 0x640, 0x00000040,
+ 0x642, 0x00000040,
+ 0x643, 0x00000000,
+ 0x652, 0x000000C8,
+ 0x66E, 0x00000005,
+ 0x700, 0x00000021,
+ 0x701, 0x00000043,
+ 0x702, 0x00000065,
+ 0x703, 0x00000087,
+ 0x708, 0x00000021,
+ 0x709, 0x00000043,
+ 0x70A, 0x00000065,
+ 0x70B, 0x00000087,
+ 0x718, 0x00000040,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8821a_mac, rtw_phy_cfg_mac);
+
+static const u32 rtw8821a_agc[] = {
+ 0x81C, 0xBF000001,
+ 0x81C, 0xBF020001,
+ 0x81C, 0xBF040001,
+ 0x81C, 0xBF060001,
+ 0x81C, 0xBE080001,
+ 0x81C, 0xBD0A0001,
+ 0x81C, 0xBC0C0001,
+ 0x81C, 0xBA0E0001,
+ 0x81C, 0xB9100001,
+ 0x81C, 0xB8120001,
+ 0x81C, 0xB7140001,
+ 0x81C, 0xB6160001,
+ 0x81C, 0xB5180001,
+ 0x81C, 0xB41A0001,
+ 0x81C, 0xB31C0001,
+ 0x81C, 0xB21E0001,
+ 0x81C, 0xB1200001,
+ 0x81C, 0xB0220001,
+ 0x81C, 0xAF240001,
+ 0x81C, 0xAE260001,
+ 0x81C, 0xAD280001,
+ 0x81C, 0xAC2A0001,
+ 0x81C, 0xAB2C0001,
+ 0x81C, 0xAA2E0001,
+ 0x81C, 0xA9300001,
+ 0x81C, 0xA8320001,
+ 0x81C, 0xA7340001,
+ 0x81C, 0xA6360001,
+ 0x81C, 0xA5380001,
+ 0x81C, 0xA43A0001,
+ 0x81C, 0x683C0001,
+ 0x81C, 0x673E0001,
+ 0x81C, 0x66400001,
+ 0x81C, 0x65420001,
+ 0x81C, 0x64440001,
+ 0x81C, 0x63460001,
+ 0x81C, 0x62480001,
+ 0x81C, 0x614A0001,
+ 0x81C, 0x474C0001,
+ 0x81C, 0x464E0001,
+ 0x81C, 0x45500001,
+ 0x81C, 0x44520001,
+ 0x81C, 0x43540001,
+ 0x81C, 0x42560001,
+ 0x81C, 0x41580001,
+ 0x81C, 0x285A0001,
+ 0x81C, 0x275C0001,
+ 0x81C, 0x265E0001,
+ 0x81C, 0x25600001,
+ 0x81C, 0x24620001,
+ 0x81C, 0x0A640001,
+ 0x81C, 0x09660001,
+ 0x81C, 0x08680001,
+ 0x81C, 0x076A0001,
+ 0x81C, 0x066C0001,
+ 0x81C, 0x056E0001,
+ 0x81C, 0x04700001,
+ 0x81C, 0x03720001,
+ 0x81C, 0x02740001,
+ 0x81C, 0x01760001,
+ 0x81C, 0x01780001,
+ 0x81C, 0x017A0001,
+ 0x81C, 0x017C0001,
+ 0x81C, 0x017E0001,
+ 0x8000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFB000101,
+ 0x81C, 0xFA020101,
+ 0x81C, 0xF9040101,
+ 0x81C, 0xF8060101,
+ 0x81C, 0xF7080101,
+ 0x81C, 0xF60A0101,
+ 0x81C, 0xF50C0101,
+ 0x81C, 0xF40E0101,
+ 0x81C, 0xF3100101,
+ 0x81C, 0xF2120101,
+ 0x81C, 0xF1140101,
+ 0x81C, 0xF0160101,
+ 0x81C, 0xEF180101,
+ 0x81C, 0xEE1A0101,
+ 0x81C, 0xED1C0101,
+ 0x81C, 0xEC1E0101,
+ 0x81C, 0xEB200101,
+ 0x81C, 0xEA220101,
+ 0x81C, 0xE9240101,
+ 0x81C, 0xE8260101,
+ 0x81C, 0xE7280101,
+ 0x81C, 0xE62A0101,
+ 0x81C, 0xE52C0101,
+ 0x81C, 0xE42E0101,
+ 0x81C, 0xE3300101,
+ 0x81C, 0xA5320101,
+ 0x81C, 0xA4340101,
+ 0x81C, 0xA3360101,
+ 0x81C, 0x87380101,
+ 0x81C, 0x863A0101,
+ 0x81C, 0x853C0101,
+ 0x81C, 0x843E0101,
+ 0x81C, 0x69400101,
+ 0x81C, 0x68420101,
+ 0x81C, 0x67440101,
+ 0x81C, 0x66460101,
+ 0x81C, 0x49480101,
+ 0x81C, 0x484A0101,
+ 0x81C, 0x474C0101,
+ 0x81C, 0x2A4E0101,
+ 0x81C, 0x29500101,
+ 0x81C, 0x28520101,
+ 0x81C, 0x27540101,
+ 0x81C, 0x26560101,
+ 0x81C, 0x25580101,
+ 0x81C, 0x245A0101,
+ 0x81C, 0x235C0101,
+ 0x81C, 0x055E0101,
+ 0x81C, 0x04600101,
+ 0x81C, 0x03620101,
+ 0x81C, 0x02640101,
+ 0x81C, 0x01660101,
+ 0x81C, 0x01680101,
+ 0x81C, 0x016A0101,
+ 0x81C, 0x016C0101,
+ 0x81C, 0x016E0101,
+ 0x81C, 0x01700101,
+ 0x81C, 0x01720101,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFB000101,
+ 0x81C, 0xFA020101,
+ 0x81C, 0xF9040101,
+ 0x81C, 0xF8060101,
+ 0x81C, 0xF7080101,
+ 0x81C, 0xF60A0101,
+ 0x81C, 0xF50C0101,
+ 0x81C, 0xF40E0101,
+ 0x81C, 0xF3100101,
+ 0x81C, 0xF2120101,
+ 0x81C, 0xF1140101,
+ 0x81C, 0xF0160101,
+ 0x81C, 0xEF180101,
+ 0x81C, 0xEE1A0101,
+ 0x81C, 0xED1C0101,
+ 0x81C, 0xEC1E0101,
+ 0x81C, 0xEB200101,
+ 0x81C, 0xEA220101,
+ 0x81C, 0xE9240101,
+ 0x81C, 0xE8260101,
+ 0x81C, 0xE7280101,
+ 0x81C, 0xE62A0101,
+ 0x81C, 0xE52C0101,
+ 0x81C, 0xE42E0101,
+ 0x81C, 0xE3300101,
+ 0x81C, 0xA5320101,
+ 0x81C, 0xA4340101,
+ 0x81C, 0xA3360101,
+ 0x81C, 0x87380101,
+ 0x81C, 0x863A0101,
+ 0x81C, 0x853C0101,
+ 0x81C, 0x843E0101,
+ 0x81C, 0x69400101,
+ 0x81C, 0x68420101,
+ 0x81C, 0x67440101,
+ 0x81C, 0x66460101,
+ 0x81C, 0x49480101,
+ 0x81C, 0x484A0101,
+ 0x81C, 0x474C0101,
+ 0x81C, 0x2A4E0101,
+ 0x81C, 0x29500101,
+ 0x81C, 0x28520101,
+ 0x81C, 0x27540101,
+ 0x81C, 0x26560101,
+ 0x81C, 0x25580101,
+ 0x81C, 0x245A0101,
+ 0x81C, 0x235C0101,
+ 0x81C, 0x055E0101,
+ 0x81C, 0x04600101,
+ 0x81C, 0x03620101,
+ 0x81C, 0x02640101,
+ 0x81C, 0x01660101,
+ 0x81C, 0x01680101,
+ 0x81C, 0x016A0101,
+ 0x81C, 0x016C0101,
+ 0x81C, 0x016E0101,
+ 0x81C, 0x01700101,
+ 0x81C, 0x01720101,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFF000101,
+ 0x81C, 0xFF020101,
+ 0x81C, 0xFE040101,
+ 0x81C, 0xFD060101,
+ 0x81C, 0xFC080101,
+ 0x81C, 0xFD0A0101,
+ 0x81C, 0xFC0C0101,
+ 0x81C, 0xFB0E0101,
+ 0x81C, 0xFA100101,
+ 0x81C, 0xF9120101,
+ 0x81C, 0xF8140101,
+ 0x81C, 0xF7160101,
+ 0x81C, 0xF6180101,
+ 0x81C, 0xF51A0101,
+ 0x81C, 0xF41C0101,
+ 0x81C, 0xF31E0101,
+ 0x81C, 0xF2200101,
+ 0x81C, 0xF1220101,
+ 0x81C, 0xF0240101,
+ 0x81C, 0xEF260101,
+ 0x81C, 0xEE280101,
+ 0x81C, 0xED2A0101,
+ 0x81C, 0xEC2C0101,
+ 0x81C, 0xEB2E0101,
+ 0x81C, 0xEA300101,
+ 0x81C, 0xE9320101,
+ 0x81C, 0xE8340101,
+ 0x81C, 0xE7360101,
+ 0x81C, 0xE6380101,
+ 0x81C, 0xE53A0101,
+ 0x81C, 0xE43C0101,
+ 0x81C, 0xE33E0101,
+ 0x81C, 0xA5400101,
+ 0x81C, 0xA4420101,
+ 0x81C, 0xA3440101,
+ 0x81C, 0x87460101,
+ 0x81C, 0x86480101,
+ 0x81C, 0x854A0101,
+ 0x81C, 0x844C0101,
+ 0x81C, 0x694E0101,
+ 0x81C, 0x68500101,
+ 0x81C, 0x67520101,
+ 0x81C, 0x66540101,
+ 0x81C, 0x49560101,
+ 0x81C, 0x48580101,
+ 0x81C, 0x475A0101,
+ 0x81C, 0x2A5C0101,
+ 0x81C, 0x295E0101,
+ 0x81C, 0x28600101,
+ 0x81C, 0x27620101,
+ 0x81C, 0x26640101,
+ 0x81C, 0x25660101,
+ 0x81C, 0x24680101,
+ 0x81C, 0x236A0101,
+ 0x81C, 0x056C0101,
+ 0x81C, 0x046E0101,
+ 0x81C, 0x03700101,
+ 0x81C, 0x02720101,
+ 0xB0000000, 0x00000000,
+ 0x81C, 0x01740101,
+ 0x81C, 0x01760101,
+ 0x81C, 0x01780101,
+ 0x81C, 0x017A0101,
+ 0x81C, 0x017C0101,
+ 0x81C, 0x017E0101,
+ 0xC50, 0x00000022,
+ 0xC50, 0x00000020,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8821a_agc, rtw_phy_cfg_agc);
+
+static const u32 rtw8821a_bb[] = {
+ 0x800, 0x0020D090,
+ 0x804, 0x080112E0,
+ 0x808, 0x0E028211,
+ 0x80C, 0x92131111,
+ 0x810, 0x20101261,
+ 0x814, 0x020C3D10,
+ 0x818, 0x03A00385,
+ 0x820, 0x00000000,
+ 0x824, 0x00030FE0,
+ 0x828, 0x00000000,
+ 0x82C, 0x002081DD,
+ 0x830, 0x2AAAEEC8,
+ 0x834, 0x0037A706,
+ 0x838, 0x06489B44,
+ 0x83C, 0x0000095B,
+ 0x840, 0xC0000001,
+ 0x844, 0x40003CDE,
+ 0x848, 0x62103F8B,
+ 0x84C, 0x6CFDFFB8,
+ 0x850, 0x28874706,
+ 0x854, 0x0001520C,
+ 0x858, 0x8060E000,
+ 0x85C, 0x74210168,
+ 0x860, 0x6929C321,
+ 0x864, 0x79727432,
+ 0x868, 0x8CA7A314,
+ 0x86C, 0x888C2878,
+ 0x870, 0x08888888,
+ 0x874, 0x31612C2E,
+ 0x878, 0x00000152,
+ 0x87C, 0x000FD000,
+ 0x8A0, 0x00000013,
+ 0x8A4, 0x7F7F7F7F,
+ 0x8A8, 0xA2000338,
+ 0x8AC, 0x0FF0FA0A,
+ 0x8B4, 0x000FC080,
+ 0x8B8, 0x6C10D7FF,
+ 0x8BC, 0x0CA52090,
+ 0x8C0, 0x1BF00020,
+ 0x8C4, 0x00000000,
+ 0x8C8, 0x00013169,
+ 0x8CC, 0x08248492,
+ 0x8D4, 0x940008A0,
+ 0x8D8, 0x290B5612,
+ 0x8F8, 0x400002C0,
+ 0x8FC, 0x00000000,
+ 0x900, 0x00000700,
+ 0x90C, 0x00000000,
+ 0x910, 0x0000FC00,
+ 0x914, 0x00000404,
+ 0x918, 0x1C1028C0,
+ 0x91C, 0x64B11A1C,
+ 0x920, 0xE0767233,
+ 0x924, 0x055AA500,
+ 0x928, 0x00000004,
+ 0x92C, 0xFFFE0000,
+ 0x930, 0xFFFFFFFE,
+ 0x934, 0x001FFFFF,
+ 0x960, 0x00000000,
+ 0x964, 0x00000000,
+ 0x968, 0x00000000,
+ 0x96C, 0x00000000,
+ 0x970, 0x801FFFFF,
+ 0x974, 0x000003FF,
+ 0x978, 0x00000000,
+ 0x97C, 0x00000000,
+ 0x980, 0x00000000,
+ 0x984, 0x00000000,
+ 0x988, 0x00000000,
+ 0x990, 0x27100000,
+ 0x994, 0xFFFF0100,
+ 0x998, 0xFFFFFF5C,
+ 0x99C, 0xFFFFFFFF,
+ 0x9A0, 0x000000FF,
+ 0x9A4, 0x00480080,
+ 0x9A8, 0x00000000,
+ 0x9AC, 0x00000000,
+ 0x9B0, 0x81081008,
+ 0x9B4, 0x01081008,
+ 0x9B8, 0x01081008,
+ 0x9BC, 0x01081008,
+ 0x9D0, 0x00000000,
+ 0x9D4, 0x00000000,
+ 0x9D8, 0x00000000,
+ 0x9DC, 0x00000000,
+ 0x9E0, 0x00005D00,
+ 0x9E4, 0x00000003,
+ 0x9E8, 0x00000001,
+ 0xA00, 0x00D047C8,
+ 0xA04, 0x01FF800C,
+ 0xA08, 0x8C8A8300,
+ 0xA0C, 0x2E68000F,
+ 0xA10, 0x9500BB78,
+ 0xA14, 0x11144028,
+ 0xA18, 0x00881117,
+ 0xA1C, 0x89140F00,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0xA2C, 0x00900000,
+ 0xA70, 0x101FFF00,
+ 0xA74, 0x00000008,
+ 0xA78, 0x00000900,
+ 0xA7C, 0x225B0606,
+ 0xA80, 0x21805490,
+ 0xA84, 0x001F0000,
+ 0XB00, 0x03100040,
+ 0XB04, 0x0000B000,
+ 0XB08, 0xAE0201EB,
+ 0XB0C, 0x01003207,
+ 0XB10, 0x00009807,
+ 0XB14, 0x01000000,
+ 0XB18, 0x00000002,
+ 0XB1C, 0x00000002,
+ 0XB20, 0x0000001F,
+ 0XB24, 0x03020100,
+ 0XB28, 0x07060504,
+ 0XB2C, 0x0B0A0908,
+ 0XB30, 0x0F0E0D0C,
+ 0XB34, 0x13121110,
+ 0XB38, 0x17161514,
+ 0XB3C, 0x0000003A,
+ 0XB40, 0x00000000,
+ 0XB44, 0x00000000,
+ 0XB48, 0x13000032,
+ 0XB4C, 0x48080000,
+ 0XB50, 0x00000000,
+ 0XB54, 0x00000000,
+ 0XB58, 0x00000000,
+ 0XB5C, 0x00000000,
+ 0xC00, 0x00000007,
+ 0xC04, 0x00042020,
+ 0xC08, 0x80410231,
+ 0xC0C, 0x00000000,
+ 0xC10, 0x00000100,
+ 0xC14, 0x01000000,
+ 0xC1C, 0x40000003,
+ 0xC20, 0x2C2C2C2C,
+ 0xC24, 0x30303030,
+ 0xC28, 0x30303030,
+ 0xC2C, 0x2C2C2C2C,
+ 0xC30, 0x2C2C2C2C,
+ 0xC34, 0x2C2C2C2C,
+ 0xC38, 0x2C2C2C2C,
+ 0xC3C, 0x2A2A2A2A,
+ 0xC40, 0x2A2A2A2A,
+ 0xC44, 0x2A2A2A2A,
+ 0xC48, 0x2A2A2A2A,
+ 0xC4C, 0x2A2A2A2A,
+ 0xC50, 0x00000020,
+ 0xC54, 0x001C1208,
+ 0xC58, 0x30000C1C,
+ 0xC5C, 0x00000058,
+ 0xC60, 0x34344443,
+ 0xC64, 0x07003333,
+ 0xC68, 0x19791979,
+ 0xC6C, 0x19791979,
+ 0xC70, 0x19791979,
+ 0xC74, 0x19791979,
+ 0xC78, 0x19791979,
+ 0xC7C, 0x19791979,
+ 0xC80, 0x19791979,
+ 0xC84, 0x19791979,
+ 0xC94, 0x0100005C,
+ 0xC98, 0x00000000,
+ 0xC9C, 0x00000000,
+ 0xCA0, 0x00000029,
+ 0xCA4, 0x08040201,
+ 0xCA8, 0x80402010,
+ 0xCB0, 0x77775747,
+ 0xCB4, 0x10000077,
+ 0xCB8, 0x00508240,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8821a_bb, rtw_phy_cfg_bb);
+
+static const struct rtw_phy_pg_cfg_pair rtw8821a_bb_pg[] = {
+ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, },
+ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838, },
+ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, },
+ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838, },
+ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, },
+ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, },
+ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, },
+ { 0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, },
+ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636, },
+ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, },
+ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636, },
+ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, },
+ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, },
+};
+
+RTW_DECL_TABLE_BB_PG(rtw8821a_bb_pg);
+
+static const u32 rtw8821a_rf_a[] = {
+ 0x018, 0x0001712A,
+ 0x056, 0x00051CF2,
+ 0x066, 0x00040000,
+ 0x000, 0x00010000,
+ 0x01E, 0x00080000,
+ 0x082, 0x00000830,
+ 0x083, 0x00021800,
+ 0x084, 0x00028000,
+ 0x085, 0x00048000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x0009483A,
+ 0xA0000000, 0x00000000,
+ 0x086, 0x00094838,
+ 0xB0000000, 0x00000000,
+ 0x087, 0x00044980,
+ 0x088, 0x00048000,
+ 0x089, 0x0000D480,
+ 0x08A, 0x00042240,
+ 0x08B, 0x000F0380,
+ 0x08C, 0x00090000,
+ 0x08D, 0x00022852,
+ 0x08E, 0x00065540,
+ 0x08F, 0x00088001,
+ 0x0EF, 0x00020000,
+ 0x03E, 0x00000380,
+ 0x03F, 0x00090018,
+ 0x03E, 0x00020380,
+ 0x03F, 0x000A0018,
+ 0x03E, 0x00040308,
+ 0x03F, 0x000A0018,
+ 0x03E, 0x00060018,
+ 0x03F, 0x000A0018,
+ 0x0EF, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x089, 0x00000080,
+ 0x08B, 0x00080180,
+ 0x0EF, 0x00001000,
+ 0x03A, 0x00000244,
+ 0x03B, 0x00038027,
+ 0x03C, 0x00082000,
+ 0x03A, 0x00000244,
+ 0x03B, 0x00030113,
+ 0x03C, 0x00082000,
+ 0x03A, 0x0000014C,
+ 0x03B, 0x00028027,
+ 0x03C, 0x00082000,
+ 0x03A, 0x000000CC,
+ 0x03B, 0x00027027,
+ 0x03C, 0x00042000,
+ 0x03A, 0x0000014C,
+ 0x03B, 0x0001F913,
+ 0x03C, 0x00042000,
+ 0x03A, 0x0000010C,
+ 0x03B, 0x00017F10,
+ 0x03C, 0x00012000,
+ 0x03A, 0x000000D0,
+ 0x03B, 0x00008027,
+ 0x03C, 0x000CA000,
+ 0x03A, 0x00000244,
+ 0x03B, 0x00078027,
+ 0x03C, 0x00082000,
+ 0x03A, 0x00000244,
+ 0x03B, 0x00070113,
+ 0x03C, 0x00082000,
+ 0x03A, 0x0000014C,
+ 0x03B, 0x00068027,
+ 0x03C, 0x00082000,
+ 0x03A, 0x000000CC,
+ 0x03B, 0x00067027,
+ 0x03C, 0x00042000,
+ 0x03A, 0x0000014C,
+ 0x03B, 0x0005F913,
+ 0x03C, 0x00042000,
+ 0x03A, 0x0000010C,
+ 0x03B, 0x00057F10,
+ 0x03C, 0x00012000,
+ 0x03A, 0x000000D0,
+ 0x03B, 0x00048027,
+ 0x03C, 0x000CA000,
+ 0x03A, 0x00000244,
+ 0x03B, 0x000B8027,
+ 0x03C, 0x00082000,
+ 0x03A, 0x00000244,
+ 0x03B, 0x000B0113,
+ 0x03C, 0x00082000,
+ 0x03A, 0x0000014C,
+ 0x03B, 0x000A8027,
+ 0x03C, 0x00082000,
+ 0x03A, 0x000000CC,
+ 0x03B, 0x000A7027,
+ 0x03C, 0x00042000,
+ 0x03A, 0x0000014C,
+ 0x03B, 0x0009F913,
+ 0x03C, 0x00042000,
+ 0x03A, 0x0000010C,
+ 0x03B, 0x00097F10,
+ 0x03C, 0x00012000,
+ 0x03A, 0x000000D0,
+ 0x03B, 0x00088027,
+ 0x03C, 0x000CA000,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00001100,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004ADF3,
+ 0x034, 0x00049DF0,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004ADF3,
+ 0x034, 0x00049DF0,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004ADF5,
+ 0x034, 0x00049DF2,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004A0F3,
+ 0x034, 0x000490B1,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004A0F3,
+ 0x034, 0x000490B1,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004ADF5,
+ 0x034, 0x00049DF2,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0004ADF3,
+ 0x034, 0x00049DF0,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0004ADF7,
+ 0x034, 0x00049DF3,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00048DED,
+ 0x034, 0x00047DEA,
+ 0x034, 0x00046DE7,
+ 0x034, 0x00045CE9,
+ 0x034, 0x00044CE6,
+ 0x034, 0x000438C6,
+ 0x034, 0x00042886,
+ 0x034, 0x00041486,
+ 0x034, 0x00040447,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00048DED,
+ 0x034, 0x00047DEA,
+ 0x034, 0x00046DE7,
+ 0x034, 0x00045CE9,
+ 0x034, 0x00044CE6,
+ 0x034, 0x000438C6,
+ 0x034, 0x00042886,
+ 0x034, 0x00041486,
+ 0x034, 0x00040447,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x000480AE,
+ 0x034, 0x000470AB,
+ 0x034, 0x0004608B,
+ 0x034, 0x00045069,
+ 0x034, 0x00044048,
+ 0x034, 0x00043045,
+ 0x034, 0x00042026,
+ 0x034, 0x00041023,
+ 0x034, 0x00040002,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x000480AE,
+ 0x034, 0x000470AB,
+ 0x034, 0x0004608B,
+ 0x034, 0x00045069,
+ 0x034, 0x00044048,
+ 0x034, 0x00043045,
+ 0x034, 0x00042026,
+ 0x034, 0x00041023,
+ 0x034, 0x00040002,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00048DED,
+ 0x034, 0x00047DEA,
+ 0x034, 0x00046DE7,
+ 0x034, 0x00045CE9,
+ 0x034, 0x00044CE6,
+ 0x034, 0x000438C6,
+ 0x034, 0x00042886,
+ 0x034, 0x00041486,
+ 0x034, 0x00040447,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x00048DEF,
+ 0x034, 0x00047DEC,
+ 0x034, 0x00046DE9,
+ 0x034, 0x00045CCB,
+ 0x034, 0x0004488D,
+ 0x034, 0x0004348D,
+ 0x034, 0x0004248A,
+ 0x034, 0x0004108D,
+ 0x034, 0x0004008A,
+ 0xB0000000, 0x00000000,
+ 0x80000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002ADF4,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002A0F3,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002A0F3,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0002ADF4,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0002ADF7,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00029DF4,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00029DF4,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00029DF1,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x000290F0,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x000290F0,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00029DF1,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00029DF4,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x00029DF2,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00028DF1,
+ 0x034, 0x00027DEE,
+ 0x034, 0x00026DEB,
+ 0x034, 0x00025CEC,
+ 0x034, 0x00024CE9,
+ 0x034, 0x000238CA,
+ 0x034, 0x00022889,
+ 0x034, 0x00021489,
+ 0x034, 0x0002044A,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00028DF1,
+ 0x034, 0x00027DEE,
+ 0x034, 0x00026DEB,
+ 0x034, 0x00025CEC,
+ 0x034, 0x00024CE9,
+ 0x034, 0x000238CA,
+ 0x034, 0x00022889,
+ 0x034, 0x00021489,
+ 0x034, 0x0002044A,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x000280AF,
+ 0x034, 0x000270AC,
+ 0x034, 0x0002608B,
+ 0x034, 0x00025069,
+ 0x034, 0x00024048,
+ 0x034, 0x00023045,
+ 0x034, 0x00022026,
+ 0x034, 0x00021023,
+ 0x034, 0x00020002,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x000280AF,
+ 0x034, 0x000270AC,
+ 0x034, 0x0002608B,
+ 0x034, 0x00025069,
+ 0x034, 0x00024048,
+ 0x034, 0x00023045,
+ 0x034, 0x00022026,
+ 0x034, 0x00021023,
+ 0x034, 0x00020002,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00028DF1,
+ 0x034, 0x00027DEE,
+ 0x034, 0x00026DEB,
+ 0x034, 0x00025CEC,
+ 0x034, 0x00024CE9,
+ 0x034, 0x000238CA,
+ 0x034, 0x00022889,
+ 0x034, 0x00021489,
+ 0x034, 0x0002044A,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x00028DEE,
+ 0x034, 0x00027DEB,
+ 0x034, 0x00026CCD,
+ 0x034, 0x00025CCA,
+ 0x034, 0x0002488C,
+ 0x034, 0x0002384C,
+ 0x034, 0x00022849,
+ 0x034, 0x00021449,
+ 0x034, 0x0002004D,
+ 0xB0000000, 0x00000000,
+ 0x8000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A0D7,
+ 0x034, 0x000090D3,
+ 0x034, 0x000080B1,
+ 0x034, 0x000070AE,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A0D7,
+ 0x034, 0x000090D3,
+ 0x034, 0x000080B1,
+ 0x034, 0x000070AE,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0000ADF7,
+ 0x034, 0x00009DF4,
+ 0x034, 0x00008DF1,
+ 0x034, 0x00007DEE,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00006DEB,
+ 0x034, 0x00005CEC,
+ 0x034, 0x00004CE9,
+ 0x034, 0x000038CA,
+ 0x034, 0x00002889,
+ 0x034, 0x00001489,
+ 0x034, 0x0000044A,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00006DEB,
+ 0x034, 0x00005CEC,
+ 0x034, 0x00004CE9,
+ 0x034, 0x000038CA,
+ 0x034, 0x00002889,
+ 0x034, 0x00001489,
+ 0x034, 0x0000044A,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000608D,
+ 0x034, 0x0000506B,
+ 0x034, 0x0000404A,
+ 0x034, 0x00003047,
+ 0x034, 0x00002044,
+ 0x034, 0x00001025,
+ 0x034, 0x00000004,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000608D,
+ 0x034, 0x0000506B,
+ 0x034, 0x0000404A,
+ 0x034, 0x00003047,
+ 0x034, 0x00002044,
+ 0x034, 0x00001025,
+ 0x034, 0x00000004,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x00006DEB,
+ 0x034, 0x00005CEC,
+ 0x034, 0x00004CE9,
+ 0x034, 0x000038CA,
+ 0x034, 0x00002889,
+ 0x034, 0x00001489,
+ 0x034, 0x0000044A,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x00006DCD,
+ 0x034, 0x00005CCD,
+ 0x034, 0x00004CCA,
+ 0x034, 0x0000388C,
+ 0x034, 0x00002888,
+ 0x034, 0x00001488,
+ 0x034, 0x00000486,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000040,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x035, 0x00000187,
+ 0x035, 0x00008187,
+ 0x035, 0x00010187,
+ 0x035, 0x00020188,
+ 0x035, 0x00028188,
+ 0x035, 0x00030188,
+ 0x035, 0x00040188,
+ 0x035, 0x00048188,
+ 0x035, 0x00050188,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x035, 0x00000187,
+ 0x035, 0x00008187,
+ 0x035, 0x00010187,
+ 0x035, 0x00020188,
+ 0x035, 0x00028188,
+ 0x035, 0x00030188,
+ 0x035, 0x00040188,
+ 0x035, 0x00048188,
+ 0x035, 0x00050188,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x035, 0x00000128,
+ 0x035, 0x00008128,
+ 0x035, 0x00010128,
+ 0x035, 0x000201C8,
+ 0x035, 0x000281C8,
+ 0x035, 0x000301C8,
+ 0x035, 0x000401C8,
+ 0x035, 0x000481C8,
+ 0x035, 0x000501C8,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x035, 0x00000145,
+ 0x035, 0x00008145,
+ 0x035, 0x00010145,
+ 0x035, 0x00020196,
+ 0x035, 0x00028196,
+ 0x035, 0x00030196,
+ 0x035, 0x000401C7,
+ 0x035, 0x000481C7,
+ 0x035, 0x000501C7,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x035, 0x00000128,
+ 0x035, 0x00008128,
+ 0x035, 0x00010128,
+ 0x035, 0x000201C8,
+ 0x035, 0x000281C8,
+ 0x035, 0x000301C8,
+ 0x035, 0x000401C8,
+ 0x035, 0x000481C8,
+ 0x035, 0x000501C8,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x035, 0x00000187,
+ 0x035, 0x00008187,
+ 0x035, 0x00010187,
+ 0x035, 0x00020188,
+ 0x035, 0x00028188,
+ 0x035, 0x00030188,
+ 0x035, 0x00040188,
+ 0x035, 0x00048188,
+ 0x035, 0x00050188,
+ 0xA0000000, 0x00000000,
+ 0x035, 0x00000145,
+ 0x035, 0x00008145,
+ 0x035, 0x00010145,
+ 0x035, 0x00020196,
+ 0x035, 0x00028196,
+ 0x035, 0x00030196,
+ 0x035, 0x000401C7,
+ 0x035, 0x000481C7,
+ 0x035, 0x000501C7,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000010,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x036, 0x00085733,
+ 0x036, 0x0008D733,
+ 0x036, 0x00095733,
+ 0x036, 0x0009D733,
+ 0x036, 0x000A64B4,
+ 0x036, 0x000AE4B4,
+ 0x036, 0x000B64B4,
+ 0x036, 0x000BE4B4,
+ 0x036, 0x000C64B4,
+ 0x036, 0x000CE4B4,
+ 0x036, 0x000D64B4,
+ 0x036, 0x000DE4B4,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x036, 0x00085733,
+ 0x036, 0x0008D733,
+ 0x036, 0x00095733,
+ 0x036, 0x0009D733,
+ 0x036, 0x000A64B4,
+ 0x036, 0x000AE4B4,
+ 0x036, 0x000B64B4,
+ 0x036, 0x000BE4B4,
+ 0x036, 0x000C64B4,
+ 0x036, 0x000CE4B4,
+ 0x036, 0x000D64B4,
+ 0x036, 0x000DE4B4,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x036, 0x000063B5,
+ 0x036, 0x0000E3B5,
+ 0x036, 0x000163B5,
+ 0x036, 0x0001E3B5,
+ 0x036, 0x000263B5,
+ 0x036, 0x0002E3B5,
+ 0x036, 0x000363B5,
+ 0x036, 0x0003E3B5,
+ 0x036, 0x000463B5,
+ 0x036, 0x0004E3B5,
+ 0x036, 0x000563B5,
+ 0x036, 0x0005E3B5,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x036, 0x000056B3,
+ 0x036, 0x0000D6B3,
+ 0x036, 0x000156B3,
+ 0x036, 0x0001D6B3,
+ 0x036, 0x00026634,
+ 0x036, 0x0002E634,
+ 0x036, 0x00036634,
+ 0x036, 0x0003E634,
+ 0x036, 0x000467B4,
+ 0x036, 0x0004E7B4,
+ 0x036, 0x000567B4,
+ 0x036, 0x0005E7B4,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x036, 0x000063B5,
+ 0x036, 0x0000E3B5,
+ 0x036, 0x000163B5,
+ 0x036, 0x0001E3B5,
+ 0x036, 0x000263B5,
+ 0x036, 0x0002E3B5,
+ 0x036, 0x000363B5,
+ 0x036, 0x0003E3B5,
+ 0x036, 0x000463B5,
+ 0x036, 0x0004E3B5,
+ 0x036, 0x000563B5,
+ 0x036, 0x0005E3B5,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x036, 0x00085733,
+ 0x036, 0x0008D733,
+ 0x036, 0x00095733,
+ 0x036, 0x0009D733,
+ 0x036, 0x000A64B4,
+ 0x036, 0x000AE4B4,
+ 0x036, 0x000B64B4,
+ 0x036, 0x000BE4B4,
+ 0x036, 0x000C64B4,
+ 0x036, 0x000CE4B4,
+ 0x036, 0x000D64B4,
+ 0x036, 0x000DE4B4,
+ 0xA0000000, 0x00000000,
+ 0x036, 0x000056B3,
+ 0x036, 0x0000D6B3,
+ 0x036, 0x000156B3,
+ 0x036, 0x0001D6B3,
+ 0x036, 0x00026634,
+ 0x036, 0x0002E634,
+ 0x036, 0x00036634,
+ 0x036, 0x0003E634,
+ 0x036, 0x000467B4,
+ 0x036, 0x0004E7B4,
+ 0x036, 0x000567B4,
+ 0x036, 0x0005E7B4,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00000008,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000001C8,
+ 0x03C, 0x00000492,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000001C8,
+ 0x03C, 0x00000492,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000001B6,
+ 0x03C, 0x00000492,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x0000022A,
+ 0x03C, 0x00000594,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000001B6,
+ 0x03C, 0x00000492,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x000001C8,
+ 0x03C, 0x00000492,
+ 0xA0000000, 0x00000000,
+ 0x03C, 0x0000022A,
+ 0x03C, 0x00000594,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000800,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000800,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000800,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000820,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000820,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000800,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x03C, 0x00000800,
+ 0xA0000000, 0x00000000,
+ 0x03C, 0x00000900,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x018, 0x0001712A,
+ 0x0EF, 0x00000002,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x0004E400,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x0004E400,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x00002000,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x00002000,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x00002000,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x00002000,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x008, 0x0004E400,
+ 0xA0000000, 0x00000000,
+ 0x008, 0x00002000,
+ 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x0DF, 0x000000C0,
+ 0x01F, 0x00000064,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x058, 0x000A7284,
+ 0x059, 0x000600EC,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x058, 0x000A7284,
+ 0x059, 0x000600EC,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x058, 0x00081184,
+ 0x059, 0x0006016C,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x058, 0x00081184,
+ 0x059, 0x0006016C,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x058, 0x00081184,
+ 0x059, 0x0006016C,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x058, 0x000A7284,
+ 0x059, 0x000600EC,
+ 0xA0000000, 0x00000000,
+ 0x058, 0x00081184,
+ 0x059, 0x0006016C,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000E8D73,
+ 0x062, 0x00093FC5,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000E8D73,
+ 0x062, 0x00093FC5,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000EFD83,
+ 0x062, 0x00093FCC,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000EAD53,
+ 0x062, 0x00093BC4,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000EFD83,
+ 0x062, 0x00093FCC,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x000E8D73,
+ 0x062, 0x00093FC5,
+ 0xA0000000, 0x00000000,
+ 0x061, 0x000EAD53,
+ 0x062, 0x00093BC4,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110E9,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110E9,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110EB,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110E9,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110E9,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110EB,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x063, 0x000110E9,
+ 0xA0000000, 0x00000000,
+ 0x063, 0x000714E9,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x064, 0x0001C27C,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x064, 0x0001C27C,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x064, 0x0001C27C,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x064, 0x0001C67C,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x064, 0x0001C27C,
+ 0x90000410, 0x00000000, 0x40000000, 0x00000000,
+ 0x064, 0x0001C27C,
+ 0xA0000000, 0x00000000,
+ 0x064, 0x0001C67C,
+ 0xB0000000, 0x00000000,
+ 0x80000111, 0x00000000, 0x40000000, 0x00000000,
+ 0x065, 0x00091016,
+ 0x90000110, 0x00000000, 0x40000000, 0x00000000,
+ 0x065, 0x00091016,
+ 0x90000210, 0x00000000, 0x40000000, 0x00000000,
+ 0x065, 0x00093016,
+ 0x9000020c, 0x00000000, 0x40000000, 0x00000000,
+ 0x065, 0x00093015,
+ 0x9000040c, 0x00000000, 0x40000000, 0x00000000,
+ 0x065, 0x00093015,
+ 0x90000200, 0x00000000, 0x40000000, 0x00000000,
+ 0x065, 0x00093016,
+ 0xA0000000, 0x00000000,
+ 0x065, 0x00091016,
+ 0xB0000000, 0x00000000,
+ 0x018, 0x00000006,
+ 0x0EF, 0x00002000,
+ 0x03B, 0x0003824B,
+ 0x03B, 0x0003024B,
+ 0x03B, 0x0002844B,
+ 0x03B, 0x00020F4B,
+ 0x03B, 0x00018F4B,
+ 0x03B, 0x000104B2,
+ 0x03B, 0x00008049,
+ 0x03B, 0x00000148,
+ 0x03B, 0x0007824B,
+ 0x03B, 0x0007024B,
+ 0x03B, 0x0006824B,
+ 0x03B, 0x00060F4B,
+ 0x03B, 0x00058F4B,
+ 0x03B, 0x000504B2,
+ 0x03B, 0x00048049,
+ 0x03B, 0x00040148,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x034, 0x0000ADF3,
+ 0x034, 0x00009DF0,
+ 0x034, 0x00008D70,
+ 0x034, 0x00007D6D,
+ 0x034, 0x00006CEE,
+ 0x034, 0x00005CCC,
+ 0x034, 0x000044EC,
+ 0x034, 0x000034AC,
+ 0x034, 0x0000246D,
+ 0x034, 0x0000106F,
+ 0x034, 0x0000006C,
+ 0x0EF, 0x00000000,
+ 0x0ED, 0x00000010,
+ 0x044, 0x0000ADF2,
+ 0x044, 0x00009DEF,
+ 0x044, 0x00008DEC,
+ 0x044, 0x00007DE9,
+ 0x044, 0x00006CEC,
+ 0x044, 0x00005CE9,
+ 0x044, 0x000044EC,
+ 0x044, 0x000034E9,
+ 0x044, 0x0000246C,
+ 0x044, 0x00001469,
+ 0x044, 0x0000006C,
+ 0x0ED, 0x00000000,
+ 0x0ED, 0x00000001,
+ 0x040, 0x00038DA7,
+ 0x040, 0x000300C2,
+ 0x040, 0x000288E2,
+ 0x040, 0x000200B8,
+ 0x040, 0x000188A5,
+ 0x040, 0x00010FBC,
+ 0x040, 0x00008F71,
+ 0x040, 0x00000240,
+ 0x0ED, 0x00000000,
+ 0x0EF, 0x000020A2,
+ 0x0DF, 0x00000080,
+ 0x035, 0x00000120,
+ 0x035, 0x00008120,
+ 0x035, 0x00010120,
+ 0x036, 0x00000085,
+ 0x036, 0x00008085,
+ 0x036, 0x00010085,
+ 0x036, 0x00018085,
+ 0x0EF, 0x00000000,
+ 0x051, 0x00000C31,
+ 0x052, 0x00000622,
+ 0x053, 0x000FC70B,
+ 0x054, 0x0000017E,
+ 0x056, 0x00051DF3,
+ 0x051, 0x00000C01,
+ 0x052, 0x000006D6,
+ 0x053, 0x000FC649,
+ 0x070, 0x00049661,
+ 0x071, 0x0007843E,
+ 0x072, 0x00000382,
+ 0x074, 0x00051400,
+ 0x035, 0x00000160,
+ 0x035, 0x00008160,
+ 0x035, 0x00010160,
+ 0x036, 0x00000124,
+ 0x036, 0x00008124,
+ 0x036, 0x00010124,
+ 0x036, 0x00018124,
+ 0x0ED, 0x0000000C,
+ 0x045, 0x00000140,
+ 0x045, 0x00008140,
+ 0x045, 0x00010140,
+ 0x046, 0x00000124,
+ 0x046, 0x00008124,
+ 0x046, 0x00010124,
+ 0x046, 0x00018124,
+ 0x0DF, 0x00000088,
+ 0x0B3, 0x000F0E18,
+ 0x0B4, 0x0001214C,
+ 0x0B7, 0x0003000C,
+ 0x01C, 0x000539D2,
+ 0x0C4, 0x000AFE00,
+ 0x018, 0x0001F12A,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x018, 0x0001712A,
+};
+
+RTW_DECL_TABLE_RF_RADIO(rtw8821a_rf_a, A);
+
+static const struct rtw_txpwr_lmt_cfg_pair rtw8821a_txpwr_lmt[] = {
+ { 0, 0, 0, 0, 1, 32, },
+ { 2, 0, 0, 0, 1, 28, },
+ { 1, 0, 0, 0, 1, 32, },
+ { 0, 0, 0, 0, 2, 32, },
+ { 2, 0, 0, 0, 2, 28, },
+ { 1, 0, 0, 0, 2, 32, },
+ { 0, 0, 0, 0, 3, 36, },
+ { 2, 0, 0, 0, 3, 28, },
+ { 1, 0, 0, 0, 3, 32, },
+ { 0, 0, 0, 0, 4, 36, },
+ { 2, 0, 0, 0, 4, 28, },
+ { 1, 0, 0, 0, 4, 32, },
+ { 0, 0, 0, 0, 5, 36, },
+ { 2, 0, 0, 0, 5, 28, },
+ { 1, 0, 0, 0, 5, 32, },
+ { 0, 0, 0, 0, 6, 36, },
+ { 2, 0, 0, 0, 6, 28, },
+ { 1, 0, 0, 0, 6, 32, },
+ { 0, 0, 0, 0, 7, 36, },
+ { 2, 0, 0, 0, 7, 28, },
+ { 1, 0, 0, 0, 7, 32, },
+ { 0, 0, 0, 0, 8, 36, },
+ { 2, 0, 0, 0, 8, 28, },
+ { 1, 0, 0, 0, 8, 32, },
+ { 0, 0, 0, 0, 9, 32, },
+ { 2, 0, 0, 0, 9, 28, },
+ { 1, 0, 0, 0, 9, 32, },
+ { 0, 0, 0, 0, 10, 32, },
+ { 2, 0, 0, 0, 10, 28, },
+ { 1, 0, 0, 0, 10, 32, },
+ { 0, 0, 0, 0, 11, 32, },
+ { 2, 0, 0, 0, 11, 28, },
+ { 1, 0, 0, 0, 11, 32, },
+ { 0, 0, 0, 0, 12, 28, },
+ { 2, 0, 0, 0, 12, 28, },
+ { 1, 0, 0, 0, 12, 32, },
+ { 0, 0, 0, 0, 13, 26, },
+ { 2, 0, 0, 0, 13, 28, },
+ { 1, 0, 0, 0, 13, 32, },
+ { 0, 0, 0, 0, 14, 63, },
+ { 2, 0, 0, 0, 14, 63, },
+ { 1, 0, 0, 0, 14, 32, },
+ { 0, 0, 0, 1, 1, 30, },
+ { 2, 0, 0, 1, 1, 30, },
+ { 1, 0, 0, 1, 1, 32, },
+ { 0, 0, 0, 1, 2, 30, },
+ { 2, 0, 0, 1, 2, 32, },
+ { 1, 0, 0, 1, 2, 32, },
+ { 0, 0, 0, 1, 3, 32, },
+ { 2, 0, 0, 1, 3, 32, },
+ { 1, 0, 0, 1, 3, 32, },
+ { 0, 0, 0, 1, 4, 32, },
+ { 2, 0, 0, 1, 4, 32, },
+ { 1, 0, 0, 1, 4, 32, },
+ { 0, 0, 0, 1, 5, 32, },
+ { 2, 0, 0, 1, 5, 32, },
+ { 1, 0, 0, 1, 5, 32, },
+ { 0, 0, 0, 1, 6, 32, },
+ { 2, 0, 0, 1, 6, 32, },
+ { 1, 0, 0, 1, 6, 32, },
+ { 0, 0, 0, 1, 7, 32, },
+ { 2, 0, 0, 1, 7, 32, },
+ { 1, 0, 0, 1, 7, 32, },
+ { 0, 0, 0, 1, 8, 32, },
+ { 2, 0, 0, 1, 8, 32, },
+ { 1, 0, 0, 1, 8, 32, },
+ { 0, 0, 0, 1, 9, 30, },
+ { 2, 0, 0, 1, 9, 32, },
+ { 1, 0, 0, 1, 9, 32, },
+ { 0, 0, 0, 1, 10, 30, },
+ { 2, 0, 0, 1, 10, 32, },
+ { 1, 0, 0, 1, 10, 32, },
+ { 0, 0, 0, 1, 11, 30, },
+ { 2, 0, 0, 1, 11, 32, },
+ { 1, 0, 0, 1, 11, 32, },
+ { 0, 0, 0, 1, 12, 26, },
+ { 2, 0, 0, 1, 12, 32, },
+ { 1, 0, 0, 1, 12, 32, },
+ { 0, 0, 0, 1, 13, 24, },
+ { 2, 0, 0, 1, 13, 30, },
+ { 1, 0, 0, 1, 13, 32, },
+ { 0, 0, 0, 1, 14, 63, },
+ { 2, 0, 0, 1, 14, 63, },
+ { 1, 0, 0, 1, 14, 63, },
+ { 0, 0, 0, 2, 1, 26, },
+ { 2, 0, 0, 2, 1, 26, },
+ { 1, 0, 0, 2, 1, 32, },
+ { 0, 0, 0, 2, 2, 26, },
+ { 2, 0, 0, 2, 2, 32, },
+ { 1, 0, 0, 2, 2, 32, },
+ { 0, 0, 0, 2, 3, 32, },
+ { 2, 0, 0, 2, 3, 32, },
+ { 1, 0, 0, 2, 3, 32, },
+ { 0, 0, 0, 2, 4, 32, },
+ { 2, 0, 0, 2, 4, 32, },
+ { 1, 0, 0, 2, 4, 32, },
+ { 0, 0, 0, 2, 5, 32, },
+ { 2, 0, 0, 2, 5, 32, },
+ { 1, 0, 0, 2, 5, 32, },
+ { 0, 0, 0, 2, 6, 32, },
+ { 2, 0, 0, 2, 6, 32, },
+ { 1, 0, 0, 2, 6, 32, },
+ { 0, 0, 0, 2, 7, 32, },
+ { 2, 0, 0, 2, 7, 32, },
+ { 1, 0, 0, 2, 7, 32, },
+ { 0, 0, 0, 2, 8, 32, },
+ { 2, 0, 0, 2, 8, 32, },
+ { 1, 0, 0, 2, 8, 32, },
+ { 0, 0, 0, 2, 9, 26, },
+ { 2, 0, 0, 2, 9, 32, },
+ { 1, 0, 0, 2, 9, 32, },
+ { 0, 0, 0, 2, 10, 26, },
+ { 2, 0, 0, 2, 10, 32, },
+ { 1, 0, 0, 2, 10, 32, },
+ { 0, 0, 0, 2, 11, 26, },
+ { 2, 0, 0, 2, 11, 32, },
+ { 1, 0, 0, 2, 11, 32, },
+ { 0, 0, 0, 2, 12, 26, },
+ { 2, 0, 0, 2, 12, 32, },
+ { 1, 0, 0, 2, 12, 32, },
+ { 0, 0, 0, 2, 13, 24, },
+ { 2, 0, 0, 2, 13, 26, },
+ { 1, 0, 0, 2, 13, 32, },
+ { 0, 0, 0, 2, 14, 63, },
+ { 2, 0, 0, 2, 14, 63, },
+ { 1, 0, 0, 2, 14, 63, },
+ { 0, 0, 0, 3, 1, 30, },
+ { 2, 0, 0, 3, 1, 32, },
+ { 1, 0, 0, 3, 1, 32, },
+ { 0, 0, 0, 3, 2, 32, },
+ { 2, 0, 0, 3, 2, 32, },
+ { 1, 0, 0, 3, 2, 32, },
+ { 0, 0, 0, 3, 3, 32, },
+ { 2, 0, 0, 3, 3, 32, },
+ { 1, 0, 0, 3, 3, 32, },
+ { 0, 0, 0, 3, 4, 32, },
+ { 2, 0, 0, 3, 4, 32, },
+ { 1, 0, 0, 3, 4, 32, },
+ { 0, 0, 0, 3, 5, 32, },
+ { 2, 0, 0, 3, 5, 32, },
+ { 1, 0, 0, 3, 5, 32, },
+ { 0, 0, 0, 3, 6, 32, },
+ { 2, 0, 0, 3, 6, 32, },
+ { 1, 0, 0, 3, 6, 32, },
+ { 0, 0, 0, 3, 7, 32, },
+ { 2, 0, 0, 3, 7, 32, },
+ { 1, 0, 0, 3, 7, 32, },
+ { 0, 0, 0, 3, 8, 32, },
+ { 2, 0, 0, 3, 8, 32, },
+ { 1, 0, 0, 3, 8, 32, },
+ { 0, 0, 0, 3, 9, 32, },
+ { 2, 0, 0, 3, 9, 32, },
+ { 1, 0, 0, 3, 9, 32, },
+ { 0, 0, 0, 3, 10, 32, },
+ { 2, 0, 0, 3, 10, 32, },
+ { 1, 0, 0, 3, 10, 32, },
+ { 0, 0, 0, 3, 11, 30, },
+ { 2, 0, 0, 3, 11, 32, },
+ { 1, 0, 0, 3, 11, 32, },
+ { 0, 0, 0, 3, 12, 63, },
+ { 2, 0, 0, 3, 12, 32, },
+ { 1, 0, 0, 3, 12, 32, },
+ { 0, 0, 0, 3, 13, 63, },
+ { 2, 0, 0, 3, 13, 32, },
+ { 1, 0, 0, 3, 13, 32, },
+ { 0, 0, 0, 3, 14, 63, },
+ { 2, 0, 0, 3, 14, 63, },
+ { 1, 0, 0, 3, 14, 63, },
+ { 0, 0, 1, 2, 1, 63, },
+ { 2, 0, 1, 2, 1, 63, },
+ { 1, 0, 1, 2, 1, 63, },
+ { 0, 0, 1, 2, 2, 63, },
+ { 2, 0, 1, 2, 2, 63, },
+ { 1, 0, 1, 2, 2, 63, },
+ { 0, 0, 1, 2, 3, 26, },
+ { 2, 0, 1, 2, 3, 26, },
+ { 1, 0, 1, 2, 3, 32, },
+ { 0, 0, 1, 2, 4, 26, },
+ { 2, 0, 1, 2, 4, 32, },
+ { 1, 0, 1, 2, 4, 32, },
+ { 0, 0, 1, 2, 5, 26, },
+ { 2, 0, 1, 2, 5, 32, },
+ { 1, 0, 1, 2, 5, 32, },
+ { 0, 0, 1, 2, 6, 32, },
+ { 2, 0, 1, 2, 6, 32, },
+ { 1, 0, 1, 2, 6, 32, },
+ { 0, 0, 1, 2, 7, 32, },
+ { 2, 0, 1, 2, 7, 32, },
+ { 1, 0, 1, 2, 7, 32, },
+ { 0, 0, 1, 2, 8, 32, },
+ { 2, 0, 1, 2, 8, 32, },
+ { 1, 0, 1, 2, 8, 32, },
+ { 0, 0, 1, 2, 9, 26, },
+ { 2, 0, 1, 2, 9, 32, },
+ { 1, 0, 1, 2, 9, 32, },
+ { 0, 0, 1, 2, 10, 24, },
+ { 2, 0, 1, 2, 10, 32, },
+ { 1, 0, 1, 2, 10, 32, },
+ { 0, 0, 1, 2, 11, 22, },
+ { 2, 0, 1, 2, 11, 26, },
+ { 1, 0, 1, 2, 11, 32, },
+ { 0, 0, 1, 2, 12, 63, },
+ { 2, 0, 1, 2, 12, 63, },
+ { 1, 0, 1, 2, 12, 63, },
+ { 0, 0, 1, 2, 13, 63, },
+ { 2, 0, 1, 2, 13, 63, },
+ { 1, 0, 1, 2, 13, 63, },
+ { 0, 0, 1, 2, 14, 63, },
+ { 2, 0, 1, 2, 14, 63, },
+ { 1, 0, 1, 2, 14, 63, },
+ { 0, 0, 1, 3, 1, 63, },
+ { 2, 0, 1, 3, 1, 63, },
+ { 1, 0, 1, 3, 1, 63, },
+ { 0, 0, 1, 3, 2, 63, },
+ { 2, 0, 1, 3, 2, 63, },
+ { 1, 0, 1, 3, 2, 63, },
+ { 0, 0, 1, 3, 3, 30, },
+ { 2, 0, 1, 3, 3, 30, },
+ { 1, 0, 1, 3, 3, 30, },
+ { 0, 0, 1, 3, 4, 32, },
+ { 2, 0, 1, 3, 4, 30, },
+ { 1, 0, 1, 3, 4, 30, },
+ { 0, 0, 1, 3, 5, 32, },
+ { 2, 0, 1, 3, 5, 30, },
+ { 1, 0, 1, 3, 5, 30, },
+ { 0, 0, 1, 3, 6, 32, },
+ { 2, 0, 1, 3, 6, 30, },
+ { 1, 0, 1, 3, 6, 30, },
+ { 0, 0, 1, 3, 7, 32, },
+ { 2, 0, 1, 3, 7, 30, },
+ { 1, 0, 1, 3, 7, 30, },
+ { 0, 0, 1, 3, 8, 32, },
+ { 2, 0, 1, 3, 8, 30, },
+ { 1, 0, 1, 3, 8, 30, },
+ { 0, 0, 1, 3, 9, 32, },
+ { 2, 0, 1, 3, 9, 30, },
+ { 1, 0, 1, 3, 9, 30, },
+ { 0, 0, 1, 3, 10, 32, },
+ { 2, 0, 1, 3, 10, 30, },
+ { 1, 0, 1, 3, 10, 30, },
+ { 0, 0, 1, 3, 11, 30, },
+ { 2, 0, 1, 3, 11, 30, },
+ { 1, 0, 1, 3, 11, 30, },
+ { 0, 0, 1, 3, 12, 63, },
+ { 2, 0, 1, 3, 12, 32, },
+ { 1, 0, 1, 3, 12, 32, },
+ { 0, 0, 1, 3, 13, 63, },
+ { 2, 0, 1, 3, 13, 32, },
+ { 1, 0, 1, 3, 13, 32, },
+ { 0, 0, 1, 3, 14, 63, },
+ { 2, 0, 1, 3, 14, 63, },
+ { 1, 0, 1, 3, 14, 63, },
+ { 0, 1, 0, 1, 36, 32, },
+ { 2, 1, 0, 1, 36, 30, },
+ { 1, 1, 0, 1, 36, 30, },
+ { 0, 1, 0, 1, 40, 32, },
+ { 2, 1, 0, 1, 40, 30, },
+ { 1, 1, 0, 1, 40, 30, },
+ { 0, 1, 0, 1, 44, 32, },
+ { 2, 1, 0, 1, 44, 30, },
+ { 1, 1, 0, 1, 44, 30, },
+ { 0, 1, 0, 1, 48, 32, },
+ { 2, 1, 0, 1, 48, 30, },
+ { 1, 1, 0, 1, 48, 30, },
+ { 0, 1, 0, 1, 52, 32, },
+ { 2, 1, 0, 1, 52, 30, },
+ { 1, 1, 0, 1, 52, 30, },
+ { 0, 1, 0, 1, 56, 32, },
+ { 2, 1, 0, 1, 56, 30, },
+ { 1, 1, 0, 1, 56, 30, },
+ { 0, 1, 0, 1, 60, 32, },
+ { 2, 1, 0, 1, 60, 30, },
+ { 1, 1, 0, 1, 60, 30, },
+ { 0, 1, 0, 1, 64, 32, },
+ { 2, 1, 0, 1, 64, 30, },
+ { 1, 1, 0, 1, 64, 30, },
+ { 0, 1, 0, 1, 100, 32, },
+ { 2, 1, 0, 1, 100, 30, },
+ { 1, 1, 0, 1, 100, 30, },
+ { 0, 1, 0, 1, 104, 32, },
+ { 2, 1, 0, 1, 104, 30, },
+ { 1, 1, 0, 1, 104, 30, },
+ { 0, 1, 0, 1, 108, 32, },
+ { 2, 1, 0, 1, 108, 30, },
+ { 1, 1, 0, 1, 108, 30, },
+ { 0, 1, 0, 1, 112, 32, },
+ { 2, 1, 0, 1, 112, 30, },
+ { 1, 1, 0, 1, 112, 30, },
+ { 0, 1, 0, 1, 116, 32, },
+ { 2, 1, 0, 1, 116, 30, },
+ { 1, 1, 0, 1, 116, 30, },
+ { 0, 1, 0, 1, 120, 32, },
+ { 2, 1, 0, 1, 120, 30, },
+ { 1, 1, 0, 1, 120, 30, },
+ { 0, 1, 0, 1, 124, 32, },
+ { 2, 1, 0, 1, 124, 30, },
+ { 1, 1, 0, 1, 124, 30, },
+ { 0, 1, 0, 1, 128, 32, },
+ { 2, 1, 0, 1, 128, 30, },
+ { 1, 1, 0, 1, 128, 30, },
+ { 0, 1, 0, 1, 132, 32, },
+ { 2, 1, 0, 1, 132, 30, },
+ { 1, 1, 0, 1, 132, 30, },
+ { 0, 1, 0, 1, 136, 32, },
+ { 2, 1, 0, 1, 136, 30, },
+ { 1, 1, 0, 1, 136, 30, },
+ { 0, 1, 0, 1, 140, 32, },
+ { 2, 1, 0, 1, 140, 30, },
+ { 1, 1, 0, 1, 140, 30, },
+ { 0, 1, 0, 1, 149, 32, },
+ { 2, 1, 0, 1, 149, 30, },
+ { 1, 1, 0, 1, 149, 63, },
+ { 0, 1, 0, 1, 153, 32, },
+ { 2, 1, 0, 1, 153, 30, },
+ { 1, 1, 0, 1, 153, 63, },
+ { 0, 1, 0, 1, 157, 32, },
+ { 2, 1, 0, 1, 157, 30, },
+ { 1, 1, 0, 1, 157, 63, },
+ { 0, 1, 0, 1, 161, 32, },
+ { 2, 1, 0, 1, 161, 30, },
+ { 1, 1, 0, 1, 161, 63, },
+ { 0, 1, 0, 1, 165, 32, },
+ { 2, 1, 0, 1, 165, 30, },
+ { 1, 1, 0, 1, 165, 63, },
+ { 0, 1, 0, 2, 36, 32, },
+ { 2, 1, 0, 2, 36, 30, },
+ { 1, 1, 0, 2, 36, 30, },
+ { 0, 1, 0, 2, 40, 32, },
+ { 2, 1, 0, 2, 40, 30, },
+ { 1, 1, 0, 2, 40, 30, },
+ { 0, 1, 0, 2, 44, 32, },
+ { 2, 1, 0, 2, 44, 30, },
+ { 1, 1, 0, 2, 44, 30, },
+ { 0, 1, 0, 2, 48, 32, },
+ { 2, 1, 0, 2, 48, 30, },
+ { 1, 1, 0, 2, 48, 30, },
+ { 0, 1, 0, 2, 52, 32, },
+ { 2, 1, 0, 2, 52, 30, },
+ { 1, 1, 0, 2, 52, 30, },
+ { 0, 1, 0, 2, 56, 32, },
+ { 2, 1, 0, 2, 56, 30, },
+ { 1, 1, 0, 2, 56, 30, },
+ { 0, 1, 0, 2, 60, 32, },
+ { 2, 1, 0, 2, 60, 30, },
+ { 1, 1, 0, 2, 60, 30, },
+ { 0, 1, 0, 2, 64, 32, },
+ { 2, 1, 0, 2, 64, 30, },
+ { 1, 1, 0, 2, 64, 30, },
+ { 0, 1, 0, 2, 100, 32, },
+ { 2, 1, 0, 2, 100, 30, },
+ { 1, 1, 0, 2, 100, 30, },
+ { 0, 1, 0, 2, 104, 32, },
+ { 2, 1, 0, 2, 104, 30, },
+ { 1, 1, 0, 2, 104, 30, },
+ { 0, 1, 0, 2, 108, 32, },
+ { 2, 1, 0, 2, 108, 30, },
+ { 1, 1, 0, 2, 108, 30, },
+ { 0, 1, 0, 2, 112, 32, },
+ { 2, 1, 0, 2, 112, 30, },
+ { 1, 1, 0, 2, 112, 30, },
+ { 0, 1, 0, 2, 116, 32, },
+ { 2, 1, 0, 2, 116, 30, },
+ { 1, 1, 0, 2, 116, 30, },
+ { 0, 1, 0, 2, 120, 32, },
+ { 2, 1, 0, 2, 120, 30, },
+ { 1, 1, 0, 2, 120, 30, },
+ { 0, 1, 0, 2, 124, 32, },
+ { 2, 1, 0, 2, 124, 30, },
+ { 1, 1, 0, 2, 124, 30, },
+ { 0, 1, 0, 2, 128, 32, },
+ { 2, 1, 0, 2, 128, 30, },
+ { 1, 1, 0, 2, 128, 30, },
+ { 0, 1, 0, 2, 132, 32, },
+ { 2, 1, 0, 2, 132, 30, },
+ { 1, 1, 0, 2, 132, 30, },
+ { 0, 1, 0, 2, 136, 32, },
+ { 2, 1, 0, 2, 136, 30, },
+ { 1, 1, 0, 2, 136, 30, },
+ { 0, 1, 0, 2, 140, 32, },
+ { 2, 1, 0, 2, 140, 30, },
+ { 1, 1, 0, 2, 140, 30, },
+ { 0, 1, 0, 2, 149, 32, },
+ { 2, 1, 0, 2, 149, 30, },
+ { 1, 1, 0, 2, 149, 63, },
+ { 0, 1, 0, 2, 153, 32, },
+ { 2, 1, 0, 2, 153, 30, },
+ { 1, 1, 0, 2, 153, 63, },
+ { 0, 1, 0, 2, 157, 32, },
+ { 2, 1, 0, 2, 157, 30, },
+ { 1, 1, 0, 2, 157, 63, },
+ { 0, 1, 0, 2, 161, 32, },
+ { 2, 1, 0, 2, 161, 30, },
+ { 1, 1, 0, 2, 161, 63, },
+ { 0, 1, 0, 2, 165, 32, },
+ { 2, 1, 0, 2, 165, 30, },
+ { 1, 1, 0, 2, 165, 63, },
+ { 0, 1, 0, 3, 36, 28, },
+ { 2, 1, 0, 3, 36, 30, },
+ { 1, 1, 0, 3, 36, 30, },
+ { 0, 1, 0, 3, 40, 28, },
+ { 2, 1, 0, 3, 40, 30, },
+ { 1, 1, 0, 3, 40, 30, },
+ { 0, 1, 0, 3, 44, 28, },
+ { 2, 1, 0, 3, 44, 30, },
+ { 1, 1, 0, 3, 44, 30, },
+ { 0, 1, 0, 3, 48, 28, },
+ { 2, 1, 0, 3, 48, 30, },
+ { 1, 1, 0, 3, 48, 30, },
+ { 0, 1, 0, 3, 52, 34, },
+ { 2, 1, 0, 3, 52, 30, },
+ { 1, 1, 0, 3, 52, 30, },
+ { 0, 1, 0, 3, 56, 32, },
+ { 2, 1, 0, 3, 56, 30, },
+ { 1, 1, 0, 3, 56, 30, },
+ { 0, 1, 0, 3, 60, 30, },
+ { 2, 1, 0, 3, 60, 30, },
+ { 1, 1, 0, 3, 60, 30, },
+ { 0, 1, 0, 3, 64, 26, },
+ { 2, 1, 0, 3, 64, 30, },
+ { 1, 1, 0, 3, 64, 30, },
+ { 0, 1, 0, 3, 100, 28, },
+ { 2, 1, 0, 3, 100, 30, },
+ { 1, 1, 0, 3, 100, 30, },
+ { 0, 1, 0, 3, 104, 28, },
+ { 2, 1, 0, 3, 104, 30, },
+ { 1, 1, 0, 3, 104, 30, },
+ { 0, 1, 0, 3, 108, 30, },
+ { 2, 1, 0, 3, 108, 30, },
+ { 1, 1, 0, 3, 108, 30, },
+ { 0, 1, 0, 3, 112, 32, },
+ { 2, 1, 0, 3, 112, 30, },
+ { 1, 1, 0, 3, 112, 30, },
+ { 0, 1, 0, 3, 116, 32, },
+ { 2, 1, 0, 3, 116, 30, },
+ { 1, 1, 0, 3, 116, 30, },
+ { 0, 1, 0, 3, 120, 34, },
+ { 2, 1, 0, 3, 120, 30, },
+ { 1, 1, 0, 3, 120, 30, },
+ { 0, 1, 0, 3, 124, 32, },
+ { 2, 1, 0, 3, 124, 30, },
+ { 1, 1, 0, 3, 124, 30, },
+ { 0, 1, 0, 3, 128, 30, },
+ { 2, 1, 0, 3, 128, 30, },
+ { 1, 1, 0, 3, 128, 30, },
+ { 0, 1, 0, 3, 132, 28, },
+ { 2, 1, 0, 3, 132, 30, },
+ { 1, 1, 0, 3, 132, 30, },
+ { 0, 1, 0, 3, 136, 28, },
+ { 2, 1, 0, 3, 136, 30, },
+ { 1, 1, 0, 3, 136, 30, },
+ { 0, 1, 0, 3, 140, 26, },
+ { 2, 1, 0, 3, 140, 30, },
+ { 1, 1, 0, 3, 140, 30, },
+ { 0, 1, 0, 3, 149, 34, },
+ { 2, 1, 0, 3, 149, 30, },
+ { 1, 1, 0, 3, 149, 63, },
+ { 0, 1, 0, 3, 153, 34, },
+ { 2, 1, 0, 3, 153, 30, },
+ { 1, 1, 0, 3, 153, 63, },
+ { 0, 1, 0, 3, 157, 34, },
+ { 2, 1, 0, 3, 157, 30, },
+ { 1, 1, 0, 3, 157, 63, },
+ { 0, 1, 0, 3, 161, 34, },
+ { 2, 1, 0, 3, 161, 30, },
+ { 1, 1, 0, 3, 161, 63, },
+ { 0, 1, 0, 3, 165, 34, },
+ { 2, 1, 0, 3, 165, 30, },
+ { 1, 1, 0, 3, 165, 63, },
+ { 0, 1, 1, 2, 38, 26, },
+ { 2, 1, 1, 2, 38, 30, },
+ { 1, 1, 1, 2, 38, 30, },
+ { 0, 1, 1, 2, 46, 32, },
+ { 2, 1, 1, 2, 46, 30, },
+ { 1, 1, 1, 2, 46, 30, },
+ { 0, 1, 1, 2, 54, 32, },
+ { 2, 1, 1, 2, 54, 30, },
+ { 1, 1, 1, 2, 54, 30, },
+ { 0, 1, 1, 2, 62, 24, },
+ { 2, 1, 1, 2, 62, 30, },
+ { 1, 1, 1, 2, 62, 30, },
+ { 0, 1, 1, 2, 102, 24, },
+ { 2, 1, 1, 2, 102, 30, },
+ { 1, 1, 1, 2, 102, 30, },
+ { 0, 1, 1, 2, 110, 32, },
+ { 2, 1, 1, 2, 110, 30, },
+ { 1, 1, 1, 2, 110, 30, },
+ { 0, 1, 1, 2, 118, 32, },
+ { 2, 1, 1, 2, 118, 30, },
+ { 1, 1, 1, 2, 118, 30, },
+ { 0, 1, 1, 2, 126, 32, },
+ { 2, 1, 1, 2, 126, 30, },
+ { 1, 1, 1, 2, 126, 30, },
+ { 0, 1, 1, 2, 134, 32, },
+ { 2, 1, 1, 2, 134, 30, },
+ { 1, 1, 1, 2, 134, 30, },
+ { 0, 1, 1, 2, 151, 30, },
+ { 2, 1, 1, 2, 151, 30, },
+ { 1, 1, 1, 2, 151, 63, },
+ { 0, 1, 1, 2, 159, 32, },
+ { 2, 1, 1, 2, 159, 30, },
+ { 1, 1, 1, 2, 159, 63, },
+ { 0, 1, 1, 3, 38, 28, },
+ { 2, 1, 1, 3, 38, 30, },
+ { 1, 1, 1, 3, 38, 30, },
+ { 0, 1, 1, 3, 46, 28, },
+ { 2, 1, 1, 3, 46, 30, },
+ { 1, 1, 1, 3, 46, 30, },
+ { 0, 1, 1, 3, 54, 30, },
+ { 2, 1, 1, 3, 54, 30, },
+ { 1, 1, 1, 3, 54, 30, },
+ { 0, 1, 1, 3, 62, 30, },
+ { 2, 1, 1, 3, 62, 30, },
+ { 1, 1, 1, 3, 62, 30, },
+ { 0, 1, 1, 3, 102, 26, },
+ { 2, 1, 1, 3, 102, 30, },
+ { 1, 1, 1, 3, 102, 30, },
+ { 0, 1, 1, 3, 110, 30, },
+ { 2, 1, 1, 3, 110, 30, },
+ { 1, 1, 1, 3, 110, 30, },
+ { 0, 1, 1, 3, 118, 34, },
+ { 2, 1, 1, 3, 118, 30, },
+ { 1, 1, 1, 3, 118, 30, },
+ { 0, 1, 1, 3, 126, 32, },
+ { 2, 1, 1, 3, 126, 30, },
+ { 1, 1, 1, 3, 126, 30, },
+ { 0, 1, 1, 3, 134, 30, },
+ { 2, 1, 1, 3, 134, 30, },
+ { 1, 1, 1, 3, 134, 30, },
+ { 0, 1, 1, 3, 151, 34, },
+ { 2, 1, 1, 3, 151, 30, },
+ { 1, 1, 1, 3, 151, 63, },
+ { 0, 1, 1, 3, 159, 34, },
+ { 2, 1, 1, 3, 159, 30, },
+ { 1, 1, 1, 3, 159, 63, },
+ { 0, 1, 2, 4, 42, 22, },
+ { 2, 1, 2, 4, 42, 30, },
+ { 1, 1, 2, 4, 42, 30, },
+ { 0, 1, 2, 4, 58, 20, },
+ { 2, 1, 2, 4, 58, 30, },
+ { 1, 1, 2, 4, 58, 30, },
+ { 0, 1, 2, 4, 106, 20, },
+ { 2, 1, 2, 4, 106, 30, },
+ { 1, 1, 2, 4, 106, 30, },
+ { 0, 1, 2, 4, 122, 20, },
+ { 2, 1, 2, 4, 122, 30, },
+ { 1, 1, 2, 4, 122, 30, },
+ { 0, 1, 2, 4, 155, 28, },
+ { 2, 1, 2, 4, 155, 30, },
+ { 1, 1, 2, 4, 155, 63, },
+ { 0, 1, 2, 5, 42, 28, },
+ { 2, 1, 2, 5, 42, 30, },
+ { 1, 1, 2, 5, 42, 30, },
+ { 0, 1, 2, 5, 58, 26, },
+ { 2, 1, 2, 5, 58, 30, },
+ { 1, 1, 2, 5, 58, 30, },
+ { 0, 1, 2, 5, 106, 28, },
+ { 2, 1, 2, 5, 106, 30, },
+ { 1, 1, 2, 5, 106, 30, },
+ { 0, 1, 2, 5, 122, 32, },
+ { 2, 1, 2, 5, 122, 30, },
+ { 1, 1, 2, 5, 122, 30, },
+ { 0, 1, 2, 5, 155, 34, },
+ { 2, 1, 2, 5, 155, 30, },
+ { 1, 1, 2, 5, 155, 63, },
+};
+
+RTW_DECL_TABLE_TXPWR_LMT(rtw8821a_txpwr_lmt);
+
+static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821a[] = {
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
+ {0x004A,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0},
+ {0x0023,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4), 0},
+ {0x0301,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821a[] = {
+ {0x0020,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4), 0},
+ {0x0001,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
+ {0x0000,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2), 0},
+ {0x0075,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
+ {0x0075,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(0), 0},
+ {0x004F,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5) | BIT(4), BIT(5) | BIT(4)},
+ {0x0025,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(6), 0},
+ {0x0049,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x0063,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x0062,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0058,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x005A,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x002E,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x82},
+ {0x0010,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_lps_8821a[] = {
+ {0x0301,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0xFF},
+ {0x0522,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0xFF},
+ {0x05F8,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x05F9,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x05FA,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x05FB,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, 0xFF, 0},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0100,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x03},
+ {0x0101,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0093,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x00},
+ {0x0553,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821a[] = {
+ {0x001F,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0x004F,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0049,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(1), 0},
+ {0x0000,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ {0x0020,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821a[] = {
+ {0x0007,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x20},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
+ {0x004A,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 1},
+ {0x0023,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_POLLING, BIT(1), 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[] = {
+ trans_carddis_to_cardemu_8821a,
+ trans_cardemu_to_act_8821a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[] = {
+ trans_act_to_lps_8821a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[] = {
+ trans_act_to_cardemu_8821a,
+ trans_cardemu_to_carddis_8821a,
+ NULL
+};
+
+static const u8 rtw8821a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+static const u8 rtw8821a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+static const u8 rtw8821a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+static const u8 rtw8821a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+static const u8 rtw8821a_pwrtrk_2gb_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10
+};
+
+static const u8 rtw8821a_pwrtrk_2gb_p[] = {
+ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12
+};
+
+static const u8 rtw8821a_pwrtrk_2ga_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10
+};
+
+static const u8 rtw8821a_pwrtrk_2ga_p[] = {
+ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12
+};
+
+static const u8 rtw8821a_pwrtrk_2g_cck_b_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10
+};
+
+static const u8 rtw8821a_pwrtrk_2g_cck_b_p[] = {
+ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12
+};
+
+static const u8 rtw8821a_pwrtrk_2g_cck_a_n[] = {
+ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10
+};
+
+static const u8 rtw8821a_pwrtrk_2g_cck_a_p[] = {
+ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12
+};
+
+const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl = {
+ .pwrtrk_5gb_n[0] = rtw8821a_pwrtrk_5gb_n[0],
+ .pwrtrk_5gb_n[1] = rtw8821a_pwrtrk_5gb_n[1],
+ .pwrtrk_5gb_n[2] = rtw8821a_pwrtrk_5gb_n[2],
+ .pwrtrk_5gb_p[0] = rtw8821a_pwrtrk_5gb_p[0],
+ .pwrtrk_5gb_p[1] = rtw8821a_pwrtrk_5gb_p[1],
+ .pwrtrk_5gb_p[2] = rtw8821a_pwrtrk_5gb_p[2],
+ .pwrtrk_5ga_n[0] = rtw8821a_pwrtrk_5ga_n[0],
+ .pwrtrk_5ga_n[1] = rtw8821a_pwrtrk_5ga_n[1],
+ .pwrtrk_5ga_n[2] = rtw8821a_pwrtrk_5ga_n[2],
+ .pwrtrk_5ga_p[0] = rtw8821a_pwrtrk_5ga_p[0],
+ .pwrtrk_5ga_p[1] = rtw8821a_pwrtrk_5ga_p[1],
+ .pwrtrk_5ga_p[2] = rtw8821a_pwrtrk_5ga_p[2],
+ .pwrtrk_2gb_n = rtw8821a_pwrtrk_2gb_n,
+ .pwrtrk_2gb_p = rtw8821a_pwrtrk_2gb_p,
+ .pwrtrk_2ga_n = rtw8821a_pwrtrk_2ga_n,
+ .pwrtrk_2ga_p = rtw8821a_pwrtrk_2ga_p,
+ .pwrtrk_2g_cckb_n = rtw8821a_pwrtrk_2g_cck_b_n,
+ .pwrtrk_2g_cckb_p = rtw8821a_pwrtrk_2g_cck_b_p,
+ .pwrtrk_2g_ccka_n = rtw8821a_pwrtrk_2g_cck_a_n,
+ .pwrtrk_2g_ccka_p = rtw8821a_pwrtrk_2g_cck_a_p,
+};
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h
new file mode 100644
index 000000000000..90379ac7a817
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW8821A_TABLE_H__
+#define __RTW8821A_TABLE_H__
+
+extern const struct rtw_table rtw8821a_mac_tbl;
+extern const struct rtw_table rtw8821a_agc_tbl;
+extern const struct rtw_table rtw8821a_bb_tbl;
+extern const struct rtw_table rtw8821a_bb_pg_tbl;
+extern const struct rtw_table rtw8821a_rf_a_tbl;
+extern const struct rtw_table rtw8821a_txpwr_lmt_tbl;
+
+extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[];
+extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[];
+extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[];
+
+extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821au.c b/drivers/net/wireless/realtek/rtw88/rtw8821au.c
new file mode 100644
index 000000000000..730018773e1c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "main.h"
+#include "rtw8821a.h"
+#include "usb.h"
+
+static const struct usb_device_id rtw_8821au_id_table[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
+ {},
+};
+MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table);
+
+static struct usb_driver rtw_8821au_driver = {
+ .name = "rtw_8821au",
+ .id_table = rtw_8821au_id_table,
+ .probe = rtw_usb_probe,
+ .disconnect = rtw_usb_disconnect,
+};
+module_usb_driver(rtw_8821au_driver);
+
+MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 66c79956e8e5..0270225b9c20 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -1581,13 +1581,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8821c = {
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c),
};
-static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
- [0] = RTW_DEF_RFE(8821c, 0, 0),
- [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
- [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
- [6] = RTW_DEF_RFE(8821c, 0, 0),
-};
-
static const struct rtw_hw_reg rtw8821c_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
};
@@ -1643,6 +1636,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8821c = {
};
static const struct rtw_chip_ops rtw8821c_ops = {
+ .power_on = rtw_power_on,
+ .power_off = rtw_power_off,
.phy_set_param = rtw8821c_phy_set_param,
.read_efuse = rtw8821c_read_efuse,
.query_phy_status = query_phy_status,
@@ -1897,7 +1892,7 @@ static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = {
5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
};
-static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
+static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = {
.pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0],
.pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1],
.pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2],
@@ -1920,6 +1915,13 @@ static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p,
};
+static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
+ [0] = RTW_DEF_RFE(8821c, 0, 0, 0),
+ [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2),
+ [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2),
+ [6] = RTW_DEF_RFE(8821c, 0, 0, 0),
+};
+
static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = {
{0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
{0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
@@ -1968,6 +1970,9 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x1c,
.usb_tx_agg_desc_num = 3,
+ .hw_feature_report = true,
+ .c2h_ra_report_size = 7,
+ .old_datarate_fb_limit = false,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
@@ -1989,7 +1994,6 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
.rfe_defs = rtw8821c_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs),
.rx_ldpc = false,
- .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.bfer_su_max_num = 2,
.bfer_mu_max_num = 1,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h
index 91ed921407bb..7a33ebd612ed 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h
@@ -214,19 +214,10 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define BIT_FEN_EN BIT(26)
#define REG_INIRTS_RATE_SEL 0x0480
#define REG_HTSTFWT 0x800
-#define REG_RXPSEL 0x808
-#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
-#define REG_TXPSEL 0x80c
#define REG_RXCCAMSK 0x814
-#define REG_CCASEL 0x82c
-#define REG_PDMFTH 0x830
-#define REG_CCA2ND 0x838
#define REG_L1WT 0x83c
#define REG_L1PKWT 0x840
#define REG_MRC 0x850
-#define REG_CLKTRK 0x860
-#define REG_ADCCLK 0x8ac
-#define REG_ADC160 0x8c4
#define REG_ADC40 0x8c8
#define REG_CHFIR 0x8f0
#define REG_CDDTXP 0x93c
@@ -234,14 +225,11 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define REG_ACBB0 0x948
#define REG_ACBBRXFIR 0x94c
#define REG_ACGG2TBL 0x958
-#define REG_FAS 0x9a4
-#define REG_RXSB 0xa00
#define REG_ADCINI 0xa04
#define REG_PWRTH 0xa08
#define REG_CCA_FLTR 0xa20
#define REG_TXSF2 0xa24
#define REG_TXSF6 0xa28
-#define REG_FA_CCK 0xa5c
#define REG_RXDESC 0xa2c
#define REG_ENTXCCK 0xa80
#define BTG_LNA 0xfc84
@@ -252,12 +240,8 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define REG_PWRTH2 0xaa8
#define REG_CSRATIO 0xaaa
#define REG_TXFILTER 0xaac
-#define REG_CNTRST 0xb58
#define REG_AGCTR_A 0xc08
-#define REG_TXSCALE_A 0xc1c
#define REG_TXDFIR 0xc20
-#define REG_RXIGI_A 0xc50
-#define REG_TXAGCIDX 0xc94
#define REG_TRSW 0xca0
#define REG_RFESEL0 0xcb0
#define REG_RFESEL8 0xcb4
@@ -269,14 +253,6 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define B_WLA_SWITCH BIT(23)
#define REG_RFEINV 0xcbc
#define REG_AGCTR_B 0xe08
-#define REG_RXIGI_B 0xe50
-#define REG_CRC_CCK 0xf04
-#define REG_CRC_OFDM 0xf14
-#define REG_CRC_HT 0xf10
-#define REG_CRC_VHT 0xf0c
-#define REG_CCA_OFDM 0xf08
-#define REG_FA_OFDM 0xf48
-#define REG_CCA_CCK 0xfcc
#define REG_DMEM_CTRL 0x1080
#define BIT_WL_RST BIT(16)
#define REG_ANTWT 0x1904
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 24f76a36f23e..739809f4cab5 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2072,12 +2072,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b),
};
-static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
- [2] = RTW_DEF_RFE(8822b, 2, 2),
- [3] = RTW_DEF_RFE(8822b, 3, 0),
- [5] = RTW_DEF_RFE(8822b, 5, 5),
-};
-
static const struct rtw_hw_reg rtw8822b_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
[1] = { .addr = 0xe50, .mask = 0x7f },
@@ -2132,6 +2126,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8822b = {
};
static const struct rtw_chip_ops rtw8822b_ops = {
+ .power_on = rtw_power_on,
+ .power_off = rtw_power_off,
.phy_set_param = rtw8822b_phy_set_param,
.read_efuse = rtw8822b_read_efuse,
.query_phy_status = query_phy_status,
@@ -2430,7 +2426,7 @@ static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
10, 11, 11, 12, 12, 13, 13, 14, 14, 15
};
-static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
+static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = {
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
@@ -2453,6 +2449,12 @@ static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
};
+static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
+ [2] = RTW_DEF_RFE(8822b, 2, 2, 0),
+ [3] = RTW_DEF_RFE(8822b, 3, 0, 0),
+ [5] = RTW_DEF_RFE(8822b, 5, 5, 0),
+};
+
static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
{0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
{0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
@@ -2509,6 +2511,9 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x1c,
.usb_tx_agg_desc_num = 3,
+ .hw_feature_report = true,
+ .c2h_ra_report_size = 7,
+ .old_datarate_fb_limit = false,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
@@ -2530,7 +2535,6 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
.rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
.rfe_defs = rtw8822b_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
- .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.bfer_su_max_num = 2,
.bfer_mu_max_num = 1,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h
index cf85e63966a1..0514958fb57c 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h
@@ -151,21 +151,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define RTW8822B_EDCCA_MAX 0x7f
#define RTW8822B_EDCCA_SRC_DEF 1
#define REG_HTSTFWT 0x800
-#define REG_RXPSEL 0x808
-#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
-#define REG_TXPSEL 0x80c
#define REG_RXCCAMSK 0x814
-#define REG_CCASEL 0x82c
-#define REG_PDMFTH 0x830
-#define REG_CCA2ND 0x838
#define REG_L1WT 0x83c
#define REG_L1PKWT 0x840
#define REG_MRC 0x850
-#define REG_CLKTRK 0x860
#define REG_EDCCA_POW_MA 0x8a0
#define BIT_MA_LEVEL GENMASK(1, 0)
-#define REG_ADCCLK 0x8ac
-#define REG_ADC160 0x8c4
#define REG_ADC40 0x8c8
#define REG_EDCCA_DECISION 0x8dc
#define BIT_EDCCA_OPTION BIT(5)
@@ -176,7 +167,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define REG_ACBB0 0x948
#define REG_ACBBRXFIR 0x94c
#define REG_ACGG2TBL 0x958
-#define REG_RXSB 0xa00
#define REG_ADCINI 0xa04
#define REG_TXSF2 0xa24
#define REG_TXSF6 0xa28
@@ -184,14 +174,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define REG_ENTXCCK 0xa80
#define REG_AGCTR_A 0xc08
#define REG_TXDFIR 0xc20
-#define REG_RXIGI_A 0xc50
#define REG_TRSW 0xca0
#define REG_RFESEL0 0xcb0
#define REG_RFESEL8 0xcb4
#define REG_RFECTL 0xcb8
#define REG_RFEINV 0xcbc
#define REG_AGCTR_B 0xe08
-#define REG_RXIGI_B 0xe50
#define REG_ANTWT 0x1904
#define REG_IQKFAILMSK 0x1bf0
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index da74e66bda84..af6b76937f1d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4883,16 +4883,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822c = {
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c),
};
-static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
- [0] = RTW_DEF_RFE(8822c, 0, 0),
- [1] = RTW_DEF_RFE(8822c, 0, 0),
- [2] = RTW_DEF_RFE(8822c, 0, 0),
- [3] = RTW_DEF_RFE(8822c, 0, 0),
- [4] = RTW_DEF_RFE(8822c, 0, 0),
- [5] = RTW_DEF_RFE(8822c, 0, 5),
- [6] = RTW_DEF_RFE(8822c, 0, 0),
-};
-
static const struct rtw_hw_reg rtw8822c_dig[] = {
[0] = { .addr = 0x1d70, .mask = 0x7f },
[1] = { .addr = 0x1d70, .mask = 0x7f00 },
@@ -4947,6 +4937,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8822c = {
};
static const struct rtw_chip_ops rtw8822c_ops = {
+ .power_on = rtw_power_on,
+ .power_off = rtw_power_off,
.phy_set_param = rtw8822c_phy_set_param,
.read_efuse = rtw8822c_read_efuse,
.query_phy_status = query_phy_status,
@@ -5236,7 +5228,7 @@ static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
18, 18, 19, 20, 21, 22, 23, 24, 24, 25
};
-static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
+static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = {
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
@@ -5259,6 +5251,16 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
};
+static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
+ [0] = RTW_DEF_RFE(8822c, 0, 0, 0),
+ [1] = RTW_DEF_RFE(8822c, 0, 0, 0),
+ [2] = RTW_DEF_RFE(8822c, 0, 0, 0),
+ [3] = RTW_DEF_RFE(8822c, 0, 0, 0),
+ [4] = RTW_DEF_RFE(8822c, 0, 0, 0),
+ [5] = RTW_DEF_RFE(8822c, 0, 5, 0),
+ [6] = RTW_DEF_RFE(8822c, 0, 0, 0),
+};
+
static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
@@ -5329,6 +5331,9 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x20,
.usb_tx_agg_desc_num = 3,
+ .hw_feature_report = true,
+ .c2h_ra_report_size = 7,
+ .old_datarate_fb_limit = false,
.default_1ss_tx_path = BB_PATH_A,
.path_div_supported = true,
.ht_supported = true,
@@ -5355,7 +5360,6 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
.rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs),
.en_dis_dpd = true,
.dpd_ratemask = DIS_DPD_RATEALL,
- .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.lck_threshold = 8,
.bfer_su_max_num = 2,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
new file mode 100644
index 000000000000..71e61b9c0bec
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
@@ -0,0 +1,1989 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include <linux/usb.h>
+#include "main.h"
+#include "coex.h"
+#include "phy.h"
+#include "rtw88xxa.h"
+#include "mac.h"
+#include "reg.h"
+#include "sec.h"
+#include "debug.h"
+#include "bf.h"
+#include "efuse.h"
+#include "usb.h"
+
+void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on)
+{
+ if (on) {
+ rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
+
+ rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR);
+ rtw_write16_set(rtwdev, REG_SYS_CLKR,
+ BIT_LOADER_CLK_EN | BIT_ANA8M);
+ } else {
+ rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
+ }
+}
+EXPORT_SYMBOL(rtw88xxa_efuse_grant);
+
+static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+
+ efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) &&
+ (efuse->pa_type_2g & BIT(4));
+ efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) &&
+ (efuse->lna_type_2g & BIT(3));
+
+ efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) &&
+ (efuse->pa_type_5g & BIT(0));
+ efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) &&
+ (efuse->lna_type_5g & BIT(3));
+
+ /* For rtw_phy_cond2: */
+ if (efuse->ext_pa_2g) {
+ u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2));
+ u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6));
+
+ efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a;
+ }
+
+ if (efuse->ext_pa_5g) {
+ u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2));
+ u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6));
+
+ efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a;
+ }
+
+ if (efuse->ext_lna_2g) {
+ u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g,
+ BIT(1) | BIT(0));
+ u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g,
+ BIT(5) | BIT(4));
+
+ efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a;
+ }
+
+ if (efuse->ext_lna_5g) {
+ u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g,
+ BIT(1) | BIT(0));
+ u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g,
+ BIT(5) | BIT(4));
+
+ efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a;
+ }
+}
+
+static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev,
+ struct rtw88xxa_efuse *map)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+
+ if (map->rfe_option == 0xff) {
+ if (rtwdev->hci.type == RTW_HCI_TYPE_USB)
+ efuse->rfe_option = 0;
+ else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
+ efuse->rfe_option = 2;
+ else
+ efuse->rfe_option = 4;
+ } else if (map->rfe_option & BIT(7)) {
+ if (efuse->ext_lna_5g) {
+ if (efuse->ext_pa_5g) {
+ if (efuse->ext_lna_2g && efuse->ext_pa_2g)
+ efuse->rfe_option = 3;
+ else
+ efuse->rfe_option = 0;
+ } else {
+ efuse->rfe_option = 2;
+ }
+ } else {
+ efuse->rfe_option = 4;
+ }
+ } else {
+ efuse->rfe_option = map->rfe_option & 0x3f;
+
+ /* Due to other customer already use incorrect EFUSE map for
+ * their product. We need to add workaround to prevent to
+ * modify spec and notify all customer to revise the IC 0xca
+ * content.
+ */
+ if (efuse->rfe_option == 4 &&
+ (efuse->ext_pa_5g || efuse->ext_pa_2g ||
+ efuse->ext_lna_5g || efuse->ext_lna_2g)) {
+ if (rtwdev->hci.type == RTW_HCI_TYPE_USB)
+ efuse->rfe_option = 0;
+ else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
+ efuse->rfe_option = 2;
+ }
+ }
+}
+
+static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw_hal *hal = &rtwdev->hal;
+ u8 antenna = 0;
+ u8 wmode = 0;
+ u8 val8, i;
+
+ efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) |
+ BIT(RTW_CHANNEL_WIDTH_40) |
+ BIT(RTW_CHANNEL_WIDTH_80);
+ efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT;
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
+ efuse->hw_cap.nss = 1;
+ else
+ efuse->hw_cap.nss = 2;
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
+ goto print_hw_cap;
+
+ for (i = 0; i < 2; i++) {
+ rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8);
+
+ antenna = u8_get_bits(val8, GENMASK(7, 5));
+ if (antenna)
+ break;
+ antenna = u8_get_bits(val8, GENMASK(3, 1));
+ if (antenna)
+ break;
+ }
+
+ for (i = 0; i < 2; i++) {
+ rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8);
+
+ wmode = u8_get_bits(val8, GENMASK(3, 2));
+ if (wmode)
+ break;
+ }
+
+ if (antenna == 1) {
+ rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n");
+
+ efuse->hw_cap.nss = 1;
+ hal->rf_type = RF_1T1R;
+ hal->rf_path_num = 1;
+ hal->rf_phy_num = 1;
+ hal->antenna_tx = BB_PATH_A;
+ hal->antenna_rx = BB_PATH_A;
+ } else {
+ /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */
+ efuse->hw_cap.nss = 2;
+ hal->rf_type = RF_2T2R;
+ hal->rf_path_num = 2;
+ hal->rf_phy_num = 2;
+ hal->antenna_tx = BB_PATH_AB;
+ hal->antenna_rx = BB_PATH_AB;
+
+ if (antenna == 2 && wmode == 2) {
+ rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n");
+
+ /* Can't be EFUSE_HW_CAP_IGNORE and can't be
+ * EFUSE_HW_CAP_PTCL_VHT, so make it 1.
+ */
+ efuse->hw_cap.ptcl = 1;
+ efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80);
+ }
+ }
+
+print_hw_cap:
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n",
+ efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl,
+ efuse->hw_cap.ant_num, efuse->hw_cap.nss);
+}
+
+int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw88xxa_efuse *map;
+ int i;
+
+ if (chip->id == RTW_CHIP_TYPE_8812A)
+ rtwdev->hal.cut_version += 1;
+
+ if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
+ log_map, chip->log_efuse_size, true);
+
+ map = (struct rtw88xxa_efuse *)log_map;
+
+ efuse->rf_board_option = map->rf_board_option;
+ efuse->crystal_cap = map->xtal_k;
+ if (efuse->crystal_cap == 0xff)
+ efuse->crystal_cap = 0x20;
+ efuse->pa_type_2g = map->pa_type;
+ efuse->pa_type_5g = map->pa_type;
+ efuse->lna_type_2g = map->lna_type_2g;
+ efuse->lna_type_5g = map->lna_type_5g;
+ if (chip->id == RTW_CHIP_TYPE_8812A) {
+ rtw8812a_read_amplifier_type(rtwdev);
+ rtw8812a_read_rfe_type(rtwdev, map);
+
+ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1));
+ }
+ efuse->channel_plan = map->channel_plan;
+ efuse->country_code[0] = map->country_code[0];
+ efuse->country_code[1] = map->country_code[1];
+ efuse->bt_setting = map->rf_bt_setting;
+ efuse->regd = map->rf_board_option & 0x7;
+ efuse->thermal_meter[0] = map->thermal_meter;
+ efuse->thermal_meter[1] = map->thermal_meter;
+ efuse->thermal_meter_k = map->thermal_meter;
+ efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g;
+ efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g;
+
+ rtw88xxa_read_usb_type(rtwdev);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A)
+ efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,
+ BIT_BT_FUNC_EN);
+ else
+ efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20;
+ efuse->share_ant = !!(efuse->bt_setting & BIT(0));
+
+ /* No antenna diversity because it's disabled in the vendor driver */
+ efuse->ant_div_cfg = 0;
+
+ efuse->ant_div_type = map->rf_antenna_option;
+ if (efuse->ant_div_type == 0xff)
+ efuse->ant_div_type = 0x3;
+
+ for (i = 0; i < 4; i++)
+ efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
+
+ switch (rtw_hci_type(rtwdev)) {
+ case RTW_HCI_TYPE_USB:
+ if (chip->id == RTW_CHIP_TYPE_8821A)
+ ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr);
+ else
+ ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr);
+ break;
+ case RTW_HCI_TYPE_PCIE:
+ case RTW_HCI_TYPE_SDIO:
+ default:
+ /* unsupported now */
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(rtw88xxa_read_efuse);
+
+static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ u8 val8;
+
+ /* Reset MCU IO Wrapper */
+ rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1));
+ if (chip->id == RTW_CHIP_TYPE_8812A)
+ rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3));
+ else
+ rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0));
+
+ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1);
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2));
+
+ /* Enable MCU IO Wrapper */
+ rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1));
+ if (chip->id == RTW_CHIP_TYPE_8812A)
+ rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3));
+ else
+ rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0));
+
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2));
+}
+
+/* A lightweight deinit function */
+static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev)
+{
+ u8 val8;
+
+ if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL))
+ return;
+
+ rtw88xxa_reset_8051(rtwdev);
+ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00);
+
+ /* before BB reset should do clock gated */
+ rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6));
+
+ /* reset BB */
+ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));
+
+ /* reset RF */
+ rtw_write8(rtwdev, REG_RF_CTRL, 0);
+
+ /* reset TRX path */
+ rtw_write16(rtwdev, REG_CR, 0);
+
+ /* reset MAC, reg0x5[1], auto FSM off */
+ rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8);
+
+ /* check if reg0x5[1] auto cleared */
+ if (read_poll_timeout_atomic(rtw_read8, val8,
+ !(val8 & (APS_FSMCO_MAC_OFF >> 8)),
+ 1, 5000, false,
+ rtwdev, REG_APS_FSMCO + 1))
+ rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__);
+
+ /* reg0x5[0], auto FSM on */
+ val8 |= APS_FSMCO_MAC_ENABLE >> 8;
+ rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8);
+
+ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7));
+ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7));
+}
+
+static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ u16 val16;
+ int ret;
+
+ ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq);
+ if (ret) {
+ rtw_err(rtwdev, "power on flow failed\n");
+ return ret;
+ }
+
+ rtw_write16(rtwdev, REG_CR, 0);
+ val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN |
+ BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN |
+ BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN;
+ rtw_write16_set(rtwdev, REG_CR, val16);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A) {
+ if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0))
+ rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6));
+ }
+
+ return ret;
+}
+
+static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data)
+{
+ u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data;
+ int count = 0;
+
+ rtw_write32(rtwdev, REG_LLT_INIT, value);
+
+ do {
+ if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30)))
+ break;
+
+ if (count > 20) {
+ rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n",
+ address);
+ return -EBUSY;
+ }
+ } while (++count);
+
+ return 0;
+}
+
+static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary)
+{
+ u32 last_entry = 255;
+ int status = 0;
+ u32 i;
+
+ for (i = 0; i < boundary - 1; i++) {
+ status = rtw88xxa_llt_write(rtwdev, i, i + 1);
+ if (status)
+ return status;
+ }
+
+ status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF);
+ if (status)
+ return status;
+
+ for (i = boundary; i < last_entry; i++) {
+ status = rtw88xxa_llt_write(rtwdev, i, i + 1);
+ if (status)
+ return status;
+ }
+
+ status = rtw88xxa_llt_write(rtwdev, last_entry, boundary);
+
+ return status;
+}
+
+static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ struct rtw_fifo_conf *fifo = &rtwdev->fifo;
+ const struct rtw_page_table *pg_tbl = NULL;
+ u16 pubq_num;
+ u32 val32;
+
+ switch (rtw_hci_type(rtwdev)) {
+ case RTW_HCI_TYPE_PCIE:
+ pg_tbl = &chip->page_table[1];
+ break;
+ case RTW_HCI_TYPE_USB:
+ if (rtwdev->hci.bulkout_num == 2)
+ pg_tbl = &chip->page_table[2];
+ else if (rtwdev->hci.bulkout_num == 3)
+ pg_tbl = &chip->page_table[3];
+ else if (rtwdev->hci.bulkout_num == 4)
+ pg_tbl = &chip->page_table[4];
+ break;
+ case RTW_HCI_TYPE_SDIO:
+ pg_tbl = &chip->page_table[0];
+ break;
+ default:
+ break;
+ }
+
+ pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num -
+ pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num;
+
+ val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num);
+ rtw_write32(rtwdev, REG_RQPN_NPQ, val32);
+
+ val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num);
+ rtw_write32(rtwdev, REG_RQPN, val32);
+}
+
+static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev)
+{
+ struct rtw_fifo_conf *fifo = &rtwdev->fifo;
+
+ rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary);
+ rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary);
+ rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary);
+ rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary);
+ rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary);
+}
+
+static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ u8 bulkout_num = rtwdev->hci.bulkout_num;
+ const struct rtw_rqpn *rqpn = NULL;
+ u16 txdma_pq_map;
+
+ switch (rtw_hci_type(rtwdev)) {
+ case RTW_HCI_TYPE_PCIE:
+ rqpn = &chip->rqpn_table[1];
+ break;
+ case RTW_HCI_TYPE_USB:
+ if (bulkout_num == 2)
+ rqpn = &chip->rqpn_table[2];
+ else if (bulkout_num == 3)
+ rqpn = &chip->rqpn_table[3];
+ else if (bulkout_num == 4)
+ rqpn = &chip->rqpn_table[4];
+ else
+ return -EINVAL;
+ break;
+ case RTW_HCI_TYPE_SDIO:
+ rqpn = &chip->rqpn_table[0];
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rtwdev->fifo.rqpn = rqpn;
+
+ txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7;
+ txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi);
+ txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg);
+ txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk);
+ txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be);
+ txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi);
+ txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo);
+ rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map);
+
+ /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */
+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4)
+ rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff);
+
+ return 0;
+}
+
+static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev)
+{
+ rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff);
+ rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400);
+ rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);
+
+ rtw_write32(rtwdev, REG_MAR, 0xffffffff);
+ rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff);
+}
+
+static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev)
+{
+ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1);
+ rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030);
+}
+
+static void rtw88xxa_init_edca(struct rtw_dev *rtwdev)
+{
+ rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a);
+ rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a);
+
+ rtw_write16(rtwdev, REG_SIFS, 0x100a);
+ rtw_write16(rtwdev, REG_SIFS + 2, 0x100a);
+
+ rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B);
+ rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F);
+ rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324);
+ rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226);
+
+ rtw_write8(rtwdev, REG_USTIME_TSF, 0x50);
+ rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50);
+}
+
+static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+
+ rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0,
+ chip->usb_tx_agg_desc_num);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A)
+ rtw_write8(rtwdev, REG_DWBCN1_CTRL,
+ chip->usb_tx_agg_desc_num << 1);
+}
+
+static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev)
+{
+ u16 val16;
+
+ val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT;
+ if (rtwdev->efuse.btcoex)
+ val16 |= BIT_EN_BCN_FUNCTION;
+ rtw_write16(rtwdev, REG_BCN_CTRL, val16);
+
+ rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME);
+ rtw_write8(rtwdev, REG_DRVERLYINT, 0x05);
+ rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
+ rtw_write16(rtwdev, REG_BCNTCFG, 0x4413);
+}
+
+static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev)
+{
+ u8 val8, crystal_cap;
+
+ /* power on BB/RF domain */
+ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
+ val8 |= BIT_FEN_USBA;
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8);
+
+ /* toggle BB reset */
+ val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST;
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8);
+
+ rtw_write8(rtwdev, REG_RF_CTRL,
+ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+ rtw_write8(rtwdev, REG_RF_B_CTRL,
+ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+
+ rtw_load_table(rtwdev, rtwdev->chip->bb_tbl);
+ rtw_load_table(rtwdev, rtwdev->chip->agc_tbl);
+
+ crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000,
+ crystal_cap | (crystal_cap << 6));
+ else
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000,
+ crystal_cap | (crystal_cap << 6));
+}
+
+static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev)
+{
+ u8 rf_path;
+
+ for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++)
+ rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]);
+}
+
+static void rtw8812a_config_1t(struct rtw_dev *rtwdev)
+{
+ /* BB OFDM RX Path_A */
+ rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11);
+
+ /* BB OFDM TX Path_A */
+ rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111);
+
+ /* BB CCK R/Rx Path_A */
+ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0);
+
+ /* MCS support */
+ rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4);
+
+ /* RF Path_B HSSI OFF */
+ rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4);
+
+ /* RF Path_B Power Down */
+ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0);
+
+ /* ADDA Path_B OFF */
+ rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0);
+ rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0);
+}
+
+static const u32 rtw88xxa_txscale_tbl[] = {
+ 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
+ 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
+ 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
+ 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
+};
+
+static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path)
+{
+ static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6};
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ u8 tx_bb_swing;
+
+ if (band == RTW_BAND_2G)
+ tx_bb_swing = efuse->tx_bb_swing_setting_2g;
+ else
+ tx_bb_swing = efuse->tx_bb_swing_setting_5g;
+
+ if (path == RF_PATH_B)
+ tx_bb_swing >>= 2;
+ tx_bb_swing &= 0x3;
+
+ return swing2setting[tx_bb_swing];
+}
+
+static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev)
+{
+ u32 swing, table_value;
+ u8 i;
+
+ swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type,
+ RF_PATH_A);
+
+ for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) {
+ table_value = rtw88xxa_txscale_tbl[i];
+ if (swing == table_value)
+ return i;
+ }
+
+ return 24;
+}
+
+static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 path;
+
+ dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev);
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
+ dm_info->default_cck_index = 0;
+ else
+ dm_info->default_cck_index = 24;
+
+ for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
+ ewma_thermal_init(&dm_info->avg_thermal[path]);
+ dm_info->delta_power_index[path] = 0;
+ dm_info->delta_power_index_last[path] = 0;
+ }
+
+ dm_info->pwr_trk_triggered = false;
+ dm_info->pwr_trk_init_trigger = true;
+ dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
+}
+
+void rtw88xxa_power_off(struct rtw_dev *rtwdev,
+ const struct rtw_pwr_seq_cmd *const *enter_lps_flow)
+{
+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+ enum usb_device_speed speed = rtwusb->udev->speed;
+ u16 ori_fsmc0;
+ u8 reg_cr;
+
+ reg_cr = rtw_read8(rtwdev, REG_CR);
+
+ /* Already powered off */
+ if (reg_cr == 0 || reg_cr == 0xEA)
+ return;
+
+ rtw_hci_stop(rtwdev);
+
+ if (!rtwdev->efuse.btcoex)
+ rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC);
+
+ /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */
+ if (speed == USB_SPEED_SUPER)
+ rtw_write8_set(rtwdev, REG_USB_MOD, 0x18);
+
+ rtw_write32(rtwdev, REG_HISR0, 0xffffffff);
+ rtw_write32(rtwdev, REG_HISR1, 0xffffffff);
+ rtw_write32(rtwdev, REG_HIMR0, 0);
+ rtw_write32(rtwdev, REG_HIMR1, 0);
+
+ if (rtwdev->efuse.btcoex)
+ rtw_coex_power_off_setting(rtwdev);
+
+ ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO);
+ rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN);
+
+ /* Stop Tx Report Timer. */
+ rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1));
+
+ /* Stop Rx */
+ rtw_write8(rtwdev, REG_CR, 0);
+
+ rtw_pwr_seq_parser(rtwdev, enter_lps_flow);
+
+ if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)
+ rtw88xxa_reset_8051(rtwdev);
+
+ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2));
+ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0);
+
+ rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq);
+
+ if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN)
+ rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN);
+
+ clear_bit(RTW_FLAG_POWERON, rtwdev->flags);
+}
+EXPORT_SYMBOL(rtw88xxa_power_off);
+
+static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band)
+{
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK,
+ rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A));
+ rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK,
+ rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B));
+ rtw88xxa_pwrtrack_init(rtwdev);
+}
+
+static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band)
+{
+ rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0);
+ rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7);
+
+ if (band == RTW_BAND_2G)
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1);
+ else
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2);
+}
+
+static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+
+ /* Turn off RF PA and LNA */
+
+ /* 0xCB0[15:12] = 0x7 (LNA_On)*/
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7);
+ /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7);
+
+ if (efuse->ext_lna_2g) {
+ /* Turn on 2.4G External LNA */
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0);
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2);
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2);
+ } else {
+ /* Bypass 2.4G External LNA */
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0);
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7);
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7);
+ }
+}
+
+static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev)
+{
+ /* Turn ON RF PA and LNA */
+
+ /* 0xCB0[15:12] = 0x7 (LNA_On)*/
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5);
+ /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4);
+
+ /* Bypass 2.4G External LNA */
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0);
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7);
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7);
+}
+
+static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev)
+{
+ switch (rtwdev->efuse.rfe_option) {
+ case 0:
+ case 2:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
+ break;
+ case 1:
+ if (rtwdev->efuse.btcoex) {
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
+ } else {
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
+ }
+ break;
+ case 3:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
+ rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1);
+ break;
+ case 4:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001);
+ break;
+ case 5:
+ rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
+ rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0));
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
+ break;
+ case 6:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770);
+ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);
+ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev)
+{
+ switch (rtwdev->efuse.rfe_option) {
+ case 0:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
+ break;
+ case 1:
+ if (rtwdev->efuse.btcoex) {
+ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
+ } else {
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
+ }
+ break;
+ case 2:
+ case 4:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
+ break;
+ case 3:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
+ rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1);
+ break;
+ case 5:
+ rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777);
+ rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0));
+ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
+ break;
+ case 6:
+ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717);
+ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717);
+ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);
+ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ u16 basic_rates, reg_41a;
+
+ /* 8811au one antenna module doesn't support antenna div, so driver must
+ * control antenna band, otherwise one of the band will have issue
+ */
+ if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex &&
+ rtwdev->efuse.ant_div_cfg == 0)
+ rtw8821a_set_ext_band_switch(rtwdev, new_band);
+
+ if (new_band == RTW_BAND_2G) {
+ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A) {
+ rtw8821a_phy_set_rfe_reg_24g(rtwdev);
+
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0);
+ } else {
+ rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1);
+ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17);
+
+ if (bw == RTW_CHANNEL_WIDTH_20 &&
+ rtwdev->hal.rf_type == RF_1T1R &&
+ !rtwdev->efuse.ext_lna_2g)
+ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02);
+ else
+ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04);
+
+ rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0);
+
+ rtw8812a_phy_set_rfe_reg_24g(rtwdev);
+ }
+
+ rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1);
+ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1);
+
+ basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) |
+ BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) |
+ BIT(DESC_RATE6M) | BIT(DESC_RATE12M) |
+ BIT(DESC_RATE24M);
+ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates);
+
+ rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN);
+ } else { /* RTW_BAND_5G */
+ if (chip->id == RTW_CHIP_TYPE_8821A)
+ rtw8821a_phy_set_rfe_reg_5g(rtwdev);
+
+ rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN);
+
+ read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30,
+ 50, 2500, false, rtwdev, REG_TXPKT_EMPTY);
+
+ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A) {
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1);
+ } else {
+ rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2);
+ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15);
+ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04);
+
+ rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1);
+
+ rtw8812a_phy_set_rfe_reg_5g(rtwdev);
+ }
+
+ rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf);
+
+ basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) |
+ BIT(DESC_RATE24M);
+ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates);
+ }
+
+ rtw88xxa_set_channel_bb_swing(rtwdev, new_band);
+}
+
+int rtw88xxa_power_on(struct rtw_dev *rtwdev)
+{
+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw_hal *hal = &rtwdev->hal;
+ int ret;
+
+ if (test_bit(RTW_FLAG_POWERON, rtwdev->flags))
+ return 0;
+
+ /* Override rtw_chip_efuse_info_setup() */
+ if (chip->id == RTW_CHIP_TYPE_8821A)
+ efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,
+ BIT_BT_FUNC_EN);
+
+ /* Override rtw_chip_efuse_info_setup() */
+ if (chip->id == RTW_CHIP_TYPE_8812A)
+ rtw8812a_read_amplifier_type(rtwdev);
+
+ ret = rtw_hci_setup(rtwdev);
+ if (ret) {
+ rtw_err(rtwdev, "failed to setup hci\n");
+ goto err;
+ }
+
+ /* Revise for U2/U3 switch we can not update RF-A/B reset.
+ * Reset after MAC power on to prevent RF R/W error.
+ * Is it a right method?
+ */
+ if (chip->id == RTW_CHIP_TYPE_8812A) {
+ rtw_write8(rtwdev, REG_RF_CTRL, 5);
+ rtw_write8(rtwdev, REG_RF_CTRL, 7);
+ rtw_write8(rtwdev, REG_RF_B_CTRL, 5);
+ rtw_write8(rtwdev, REG_RF_B_CTRL, 7);
+ }
+
+ /* If HW didn't go through a complete de-initial procedure,
+ * it probably occurs some problem for double initial
+ * procedure.
+ */
+ rtw88xxau_hw_reset(rtwdev);
+
+ ret = rtw88xxau_init_power_on(rtwdev);
+ if (ret) {
+ rtw_err(rtwdev, "failed to power on\n");
+ goto err;
+ }
+
+ ret = rtw_set_trx_fifo_info(rtwdev);
+ if (ret) {
+ rtw_err(rtwdev, "failed to set trx fifo info\n");
+ goto err;
+ }
+
+ ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary);
+ if (ret) {
+ rtw_err(rtwdev, "failed to init llt\n");
+ goto err;
+ }
+
+ rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
+
+ ret = rtw_wait_firmware_completion(rtwdev);
+ if (ret) {
+ rtw_err(rtwdev, "failed to wait firmware completion\n");
+ goto err_off;
+ }
+
+ ret = rtw_download_firmware(rtwdev, &rtwdev->fw);
+ if (ret) {
+ rtw_err(rtwdev, "failed to download firmware\n");
+ goto err_off;
+ }
+
+ rtw_write8(rtwdev, REG_HMETFR, 0xf);
+
+ rtw_load_table(rtwdev, chip->mac_tbl);
+
+ rtw88xxau_init_queue_reserved_page(rtwdev);
+ rtw88xxau_init_tx_buffer_boundary(rtwdev);
+ rtw88xxau_init_queue_priority(rtwdev);
+
+ rtw_write16(rtwdev, REG_TRXFF_BNDY + 2,
+ chip->rxff_size - REPORT_BUF - 1);
+
+ if (chip->id == RTW_CHIP_TYPE_8812A)
+ rtw_write8(rtwdev, REG_PBP,
+ u8_encode_bits(PBP_512, PBP_TX_MASK) |
+ u8_encode_bits(PBP_64, PBP_RX_MASK));
+
+ rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE);
+
+ rtw_write32(rtwdev, REG_HIMR0, 0);
+ rtw_write32(rtwdev, REG_HIMR1, 0);
+
+ rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2);
+
+ rtw88xxa_init_wmac_setting(rtwdev);
+ rtw88xxa_init_adaptive_ctrl(rtwdev);
+ rtw88xxa_init_edca(rtwdev);
+
+ rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7));
+ rtw_write8(rtwdev, REG_ACKTO, 0x80);
+
+ rtw88xxau_tx_aggregation(rtwdev);
+
+ rtw88xxa_init_beacon_parameters(rtwdev);
+ rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff);
+
+ rtw_hci_interface_cfg(rtwdev);
+
+ /* usb3 rx interval */
+ rtw_write8(rtwdev, REG_USB3_RXITV, 0x01);
+
+ /* burst length=4, set 0x3400 for burst length=2 */
+ rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400);
+ rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5);
+
+ /* 0x456 = 0x70, sugguested by Zhilin */
+ if (chip->id == RTW_CHIP_TYPE_8821A)
+ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e);
+ else
+ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70);
+
+ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff);
+ rtw_write8(rtwdev, REG_USTIME_TSF, 0x50);
+ rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50);
+
+ if (rtwusb->udev->speed == USB_SPEED_SUPER)
+ /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */
+ rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3));
+
+ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU);
+
+ /* for VHT packet length 11K */
+ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18);
+
+ rtw_write8(rtwdev, REG_PIFS, 0x00);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A) {
+ /* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */
+ rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f);
+ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80);
+ rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777);
+ } else {
+ rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f);
+ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7));
+ }
+
+ /* to prevent mac is reseted by bus. */
+ rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6));
+
+ /* ARFB table 9 for 11ac 5G 2SS */
+ rtw_write32(rtwdev, REG_ARFR0, 0x00000010);
+ rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000);
+
+ /* ARFB table 10 for 11ac 5G 1SS */
+ rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010);
+ rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000);
+
+ /* ARFB table 11 for 11ac 24G 1SS */
+ rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015);
+ rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000);
+
+ /* ARFB table 12 for 11ac 24G 2SS */
+ rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015);
+ rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000);
+
+ rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN);
+
+ rtw88xxa_phy_bb_config(rtwdev);
+ rtw88xxa_phy_rf_config(rtwdev);
+
+ if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1)
+ rtw8812a_config_1t(rtwdev);
+
+ rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20);
+
+ rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30));
+
+ rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff);
+ rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff);
+ rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0);
+
+ rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5));
+
+ rtw_phy_init(rtwdev);
+
+ rtw88xxa_pwrtrack_init(rtwdev);
+
+ /* 0x4c6[3] 1: RTS BW = Data BW
+ * 0: RTS BW depends on CCA / secondary CCA result.
+ */
+ rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3));
+
+ /* enable Tx report. */
+ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f);
+
+ /* Pretx_en, for WEP/TKIP SEC */
+ rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01);
+
+ rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0);
+
+ /* Reset USB mode switch setting */
+ rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0);
+ rtw_write8(rtwdev, REG_ACLK_MON, 0x0);
+
+ rtw_write8(rtwdev, REG_USB_HRPWM, 0);
+
+ /* ack for xmit mgmt frames. */
+ rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12));
+
+ hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT,
+ BIT_CCK_RPT_FORMAT);
+
+ ret = rtw_hci_start(rtwdev);
+ if (ret) {
+ rtw_err(rtwdev, "failed to start hci\n");
+ goto err_off;
+ }
+
+ if (efuse->btcoex) {
+ rtw_coex_power_on_setting(rtwdev);
+ rtw_coex_init_hw_config(rtwdev, false);
+ }
+
+ set_bit(RTW_FLAG_POWERON, rtwdev->flags);
+
+ return 0;
+
+err_off:
+ chip->ops->power_off(rtwdev);
+
+err:
+ return ret;
+}
+EXPORT_SYMBOL(rtw88xxa_power_on);
+
+u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,
+ enum rtw_rf_path rf_path, u32 addr, u32 mask)
+{
+ static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB };
+ static const u32 read_addr[2][2] = {
+ { REG_SI_READ_A, REG_SI_READ_B },
+ { REG_PI_READ_A, REG_PI_READ_B }
+ };
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ const struct rtw_hal *hal = &rtwdev->hal;
+ bool set_cca, pi_mode;
+ u32 val;
+
+ if (rf_path >= hal->rf_phy_num) {
+ rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
+ return INV_RF_DATA;
+ }
+
+ /* CCA off to avoid reading the wrong value.
+ * Toggling CCA would affect RF 0x0, skip it.
+ */
+ set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A &&
+ hal->cut_version != RTW_CHIP_VER_CUT_C;
+
+ if (set_cca)
+ rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3));
+
+ addr &= 0xff;
+
+ pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4);
+
+ rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr);
+
+ if (chip->id == RTW_CHIP_TYPE_8821A ||
+ hal->cut_version == RTW_CHIP_VER_CUT_C)
+ udelay(20);
+
+ val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask);
+
+ /* CCA on */
+ if (set_cca)
+ rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3));
+
+ return val;
+}
+EXPORT_SYMBOL(rtw88xxa_phy_read_rf);
+
+static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+ /* C cut Item12 ADC FIFO CLOCK */
+ if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) {
+ if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11)
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3);
+ else
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2);
+
+ /* A workaround to resolve 2480Mhz spur by setting ADC clock
+ * as 160M.
+ */
+ if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) {
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3);
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1);
+ } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) {
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1);
+ } else if (bw != RTW_CHANNEL_WIDTH_80) {
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2);
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0);
+ }
+ } else {
+ /* A workaround to resolve 2480Mhz spur by setting ADC clock
+ * as 160M.
+ */
+ if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14))
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3);
+ else if (channel <= 14) /* 2.4G only */
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2);
+ }
+}
+
+static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ u32 fc_area, rf_mod_ag;
+ u8 path;
+
+ switch (channel) {
+ case 36 ... 48:
+ fc_area = 0x494;
+ break;
+ case 50 ... 64:
+ fc_area = 0x453;
+ break;
+ case 100 ... 116:
+ fc_area = 0x452;
+ break;
+ default:
+ if (channel >= 118)
+ fc_area = 0x412;
+ else
+ fc_area = 0x96a;
+ break;
+ }
+
+ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area);
+
+ for (path = 0; path < hal->rf_path_num; path++) {
+ switch (channel) {
+ case 36 ... 64:
+ rf_mod_ag = 0x101;
+ break;
+ case 100 ... 140:
+ rf_mod_ag = 0x301;
+ break;
+ default:
+ if (channel > 140)
+ rf_mod_ag = 0x501;
+ else
+ rf_mod_ag = 0x000;
+ break;
+ }
+
+ rtw_write_rf(rtwdev, path, RF_CFGCH,
+ RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag);
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
+ rtw8812a_phy_fix_spur(rtwdev, channel, bw);
+
+ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel);
+ }
+}
+
+static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw)
+{
+ u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL);
+
+ val16 &= ~BIT_RFMOD;
+ if (bw == RTW_CHANNEL_WIDTH_80)
+ val16 |= BIT_RFMOD_80M;
+ else if (bw == RTW_CHANNEL_WIDTH_40)
+ val16 |= BIT_RFMOD_40M;
+
+ rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16);
+}
+
+static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel,
+ u8 bw, u8 primary_chan_idx)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ u8 txsc40 = 0, txsc20, txsc;
+ u8 reg_837, l1pkval;
+
+ rtw88xxa_set_reg_bw(rtwdev, bw);
+
+ txsc20 = primary_chan_idx;
+ if (bw == RTW_CHANNEL_WIDTH_80) {
+ if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST)
+ txsc40 = RTW_SC_40_UPPER;
+ else
+ txsc40 = RTW_SC_40_LOWER;
+ }
+
+ txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40);
+ rtw_write8(rtwdev, REG_DATA_SC, txsc);
+
+ reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3);
+
+ switch (bw) {
+ default:
+ case RTW_CHANNEL_WIDTH_20:
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200);
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0);
+
+ if (hal->rf_type == RF_2T2R)
+ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7);
+ else
+ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8);
+
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201);
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0);
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc);
+ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc);
+
+ if (reg_837 & BIT(2)) {
+ l1pkval = 6;
+ } else {
+ if (hal->rf_type == RF_2T2R)
+ l1pkval = 7;
+ else
+ l1pkval = 8;
+ }
+
+ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval);
+
+ if (txsc == RTW_SC_20_UPPER)
+ rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
+ else
+ rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
+
+ break;
+ case RTW_CHANNEL_WIDTH_80:
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202);
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1);
+ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc);
+ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc);
+
+ if (reg_837 & BIT(2)) {
+ l1pkval = 5;
+ } else {
+ if (hal->rf_type == RF_2T2R)
+ l1pkval = 6;
+ else
+ l1pkval = 7;
+ }
+
+ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval);
+
+ break;
+ }
+}
+
+static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+ u8 path;
+
+ for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_5:
+ case RTW_CHANNEL_WIDTH_10:
+ case RTW_CHANNEL_WIDTH_20:
+ default:
+ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3);
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1);
+ break;
+ case RTW_CHANNEL_WIDTH_80:
+ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0);
+ break;
+ }
+ }
+}
+
+void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_chan_idx)
+{
+ u8 old_band, new_band;
+
+ if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN)
+ old_band = RTW_BAND_5G;
+ else
+ old_band = RTW_BAND_2G;
+
+ if (channel > 14)
+ new_band = RTW_BAND_5G;
+ else
+ new_band = RTW_BAND_2G;
+
+ if (new_band != old_band)
+ rtw88xxa_switch_band(rtwdev, new_band, bw);
+
+ rtw88xxa_switch_channel(rtwdev, channel, bw);
+
+ rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx);
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
+ rtw8812a_phy_fix_spur(rtwdev, channel, bw);
+
+ rtw88xxa_set_channel_rf(rtwdev, channel, bw);
+}
+EXPORT_SYMBOL(rtw88xxa_set_channel);
+
+void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx))
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_jaguar_phy_status_rpt *rpt;
+ u8 gain[RTW_RF_PATH_MAX], rssi, i;
+ s8 rx_pwr_db, power_a, power_b;
+ const s8 min_rx_power = -120;
+ u8 lna_idx, vga_idx;
+
+ rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status;
+
+ if (pkt_stat->rate <= DESC_RATE11M) {
+ lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX);
+ vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX);
+
+ rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx);
+
+ pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
+ pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
+ pkt_stat->signal_power = rx_pwr_db;
+ } else { /* OFDM rate */
+ gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A);
+ gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B);
+
+ for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) {
+ pkt_stat->rx_power[i] = gain[i] - 110;
+ rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1);
+ dm_info->rssi[i] = rssi;
+ }
+
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power,
+ rtwdev->hal.rf_path_num);
+
+ power_a = pkt_stat->rx_power[RF_PATH_A];
+ power_b = pkt_stat->rx_power[RF_PATH_B];
+ if (rtwdev->hal.rf_path_num == 1)
+ power_b = power_a;
+
+ pkt_stat->signal_power = max3(power_a, power_b, min_rx_power);
+ }
+}
+EXPORT_SYMBOL(rtw88xxa_query_phy_status);
+
+static void
+rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path,
+ u8 rs, u32 *phy_pwr_idx)
+{
+ static const u32 offset_txagc[2] = {
+ REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1
+ };
+ u8 rate, rate_idx, pwr_index, shift;
+ struct rtw_hal *hal = &rtwdev->hal;
+ bool write_1ss_mcs9;
+ u32 mask;
+ int j;
+
+ for (j = 0; j < rtw_rate_size[rs]; j++) {
+ rate = rtw_rate_section[rs][j];
+
+ pwr_index = hal->tx_pwr_tbl[path][rate];
+
+ shift = rate & 0x3;
+ *phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
+
+ write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 &&
+ hal->rf_path_num == 1;
+
+ if (write_1ss_mcs9)
+ mask = MASKLWORD;
+ else
+ mask = MASKDWORD;
+
+ if (shift == 0x3 || write_1ss_mcs9) {
+ rate_idx = rate & 0xfc;
+ if (rate >= DESC_RATEVHT1SS_MCS0)
+ rate_idx -= 0x10;
+
+ rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx,
+ mask, *phy_pwr_idx);
+
+ *phy_pwr_idx = 0;
+ }
+ }
+}
+
+static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw,
+ u8 channel, u8 path)
+{
+ static const u32 write_offset[] = {
+ REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B,
+ };
+ u32 power_level, write_data;
+ u8 i;
+
+ power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7];
+ write_data = 0;
+
+ for (i = 0; i < 3; i++) {
+ if (i == 0)
+ power_level -= 10;
+ else if (i == 1)
+ power_level -= 8;
+ else
+ power_level -= 6;
+
+ write_data |= max_t(u32, power_level, 2) << (i * 8);
+ }
+
+ rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data);
+}
+
+void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ u32 phy_pwr_idx = 0;
+ int rs, path;
+
+ for (path = 0; path < hal->rf_path_num; path++) {
+ for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
+ if (hal->rf_path_num == 1 &&
+ (rs == RTW_RATE_SECTION_HT_2S ||
+ rs == RTW_RATE_SECTION_VHT_2S))
+ continue;
+
+ if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) &&
+ rs > RTW_RATE_SECTION_OFDM)
+ continue;
+
+ if (hal->current_band_type == RTW_BAND_5G &&
+ rs == RTW_RATE_SECTION_CCK)
+ continue;
+
+ rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs,
+ &phy_pwr_idx);
+ }
+
+ rtw88xxa_tx_power_training(rtwdev, hal->current_band_width,
+ hal->current_channel, path);
+ }
+}
+EXPORT_SYMBOL(rtw88xxa_set_tx_power_index);
+
+void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u32 cck_fa_cnt, ofdm_fa_cnt;
+ u32 crc32_cnt, cca32_cnt;
+ u32 cck_enable;
+
+ cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28);
+ cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK);
+ ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM);
+
+ dm_info->cck_fa_cnt = cck_fa_cnt;
+ dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
+ dm_info->total_fa_cnt = ofdm_fa_cnt;
+ if (cck_enable)
+ dm_info->total_fa_cnt += cck_fa_cnt;
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK);
+ dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
+ dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
+ dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
+ dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
+ dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
+ dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
+ dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
+ dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
+
+ cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
+ dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD);
+ dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
+ if (cck_enable) {
+ cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK);
+ dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD);
+ dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
+ }
+
+ rtw_write32_set(rtwdev, REG_FAS, BIT(17));
+ rtw_write32_clr(rtwdev, REG_FAS, BIT(17));
+ rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15));
+ rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15));
+ rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
+ rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
+}
+EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics);
+
+void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev,
+ u32 *macbb_backup,
+ const u32 *backup_macbb_reg,
+ u32 macbb_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* save MACBB default value */
+ for (i = 0; i < macbb_num; i++)
+ macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]);
+}
+EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb);
+
+void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
+ const u32 *backup_afe_reg, u32 afe_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* Save AFE Parameters */
+ for (i = 0; i < afe_num; i++)
+ afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]);
+}
+EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe);
+
+void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev,
+ u32 *macbb_backup,
+ const u32 *backup_macbb_reg,
+ u32 macbb_num)
+{
+ u32 i;
+
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ /* Reload MacBB Parameters */
+ for (i = 0; i < macbb_num; i++)
+ rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]);
+}
+EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb);
+
+void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev)
+{
+ /* [31] = 0 --> Page C */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
+
+ rtw_write8(rtwdev, REG_TXPAUSE, 0x3f);
+ rtw_write32_mask(rtwdev, REG_BCN_CTRL,
+ (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0);
+
+ /* RX ante off */
+ rtw_write8(rtwdev, REG_RXPSEL, 0x00);
+
+ /* CCA off */
+ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc);
+
+ /* CCK RX path off */
+ rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf);
+}
+EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac);
+
+bool rtw88xxa_iqk_finish(int average, int threshold,
+ int *x_temp, int *y_temp, int *x, int *y,
+ bool break_inner, bool break_outer)
+{
+ bool finish = false;
+ int i, ii, dx, dy;
+
+ for (i = 0; i < average; i++) {
+ for (ii = i + 1; ii < average; ii++) {
+ dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21);
+ dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21);
+
+ if (dx < threshold && dy < threshold) {
+ *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21));
+ *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21));
+
+ *x /= 2;
+ *y /= 2;
+
+ finish = true;
+
+ if (break_inner)
+ break;
+ }
+ }
+
+ if (finish && break_outer)
+ break;
+ }
+
+ return finish;
+}
+EXPORT_SYMBOL(rtw88xxa_iqk_finish);
+
+static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path)
+{
+ static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B };
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 cck_swing_idx, ofdm_swing_idx;
+ u8 pwr_tracking_limit;
+
+ switch (tx_rate) {
+ case DESC_RATE1M ... DESC_RATE11M:
+ pwr_tracking_limit = 32;
+ break;
+ case DESC_RATE6M ... DESC_RATE48M:
+ case DESC_RATEMCS3 ... DESC_RATEMCS4:
+ case DESC_RATEMCS11 ... DESC_RATEMCS12:
+ case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4:
+ case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4:
+ pwr_tracking_limit = 30;
+ break;
+ case DESC_RATE54M:
+ case DESC_RATEMCS5 ... DESC_RATEMCS7:
+ case DESC_RATEMCS13 ... DESC_RATEMCS15:
+ case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6:
+ case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6:
+ pwr_tracking_limit = 28;
+ break;
+ case DESC_RATEMCS0 ... DESC_RATEMCS2:
+ case DESC_RATEMCS8 ... DESC_RATEMCS10:
+ case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2:
+ case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2:
+ pwr_tracking_limit = 34;
+ break;
+ case DESC_RATEVHT1SS_MCS7:
+ case DESC_RATEVHT2SS_MCS7:
+ pwr_tracking_limit = 26;
+ break;
+ default:
+ case DESC_RATEVHT1SS_MCS8:
+ case DESC_RATEVHT2SS_MCS8:
+ pwr_tracking_limit = 24;
+ break;
+ case DESC_RATEVHT1SS_MCS9:
+ case DESC_RATEVHT2SS_MCS9:
+ pwr_tracking_limit = 22;
+ break;
+ }
+
+ cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index;
+ ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index;
+
+ if (ofdm_swing_idx > pwr_tracking_limit) {
+ if (path == RF_PATH_A)
+ dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit;
+ dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit;
+
+ ofdm_swing_idx = pwr_tracking_limit;
+ } else if (ofdm_swing_idx == 0) {
+ if (path == RF_PATH_A)
+ dm_info->txagc_remnant_cck = cck_swing_idx;
+ dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx;
+ } else {
+ if (path == RF_PATH_A)
+ dm_info->txagc_remnant_cck = 0;
+ dm_info->txagc_remnant_ofdm[path] = 0;
+ }
+
+ rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21),
+ rtw88xxa_txscale_tbl[ofdm_swing_idx]);
+}
+
+void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
+ void (*do_lck)(struct rtw_dev *rtwdev),
+ void (*do_iqk)(struct rtw_dev *rtwdev))
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_hal *hal = &rtwdev->hal;
+ struct rtw_swing_table swing_table;
+ s8 remnant_pre[RTW_RF_PATH_MAX];
+ u8 thermal_value, delta, path;
+ bool need_iqk;
+
+ rtw_phy_config_swing_table(rtwdev, &swing_table);
+
+ if (rtwdev->efuse.thermal_meter[0] == 0xff) {
+ pr_err_once("efuse thermal meter is 0xff\n");
+ return;
+ }
+
+ thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
+
+ rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
+
+ need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev);
+
+ if (need_iqk && do_lck)
+ do_lck(rtwdev);
+
+ if (dm_info->pwr_trk_init_trigger)
+ dm_info->pwr_trk_init_trigger = false;
+ else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
+ RF_PATH_A))
+ goto iqk;
+
+ delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
+
+ for (path = RF_PATH_A; path < hal->rf_path_num; path++) {
+ remnant_pre[path] = dm_info->txagc_remnant_ofdm[path];
+
+ dm_info->delta_power_index[path] =
+ rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path,
+ RF_PATH_A, delta);
+
+ if (dm_info->delta_power_index[path] !=
+ dm_info->delta_power_index_last[path]) {
+ dm_info->delta_power_index_last[path] =
+ dm_info->delta_power_index[path];
+
+ rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path);
+ }
+ }
+
+ for (path = RF_PATH_A; path < hal->rf_path_num; path++) {
+ if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) {
+ rtw_phy_set_tx_power_level(rtwdev,
+ hal->current_channel);
+ break;
+ }
+ }
+
+iqk:
+ if (need_iqk)
+ do_iqk(rtwdev);
+}
+EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack);
+
+void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
+{
+ static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed};
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ /* Override rtw_phy_cck_pd_lv_link(). It implements something
+ * like type 2/3/4. We need type 1 here.
+ */
+ if (rtw_is_assoc(rtwdev)) {
+ if (dm_info->min_rssi > 60) {
+ new_lvl = CCK_PD_LV3;
+ } else if (dm_info->min_rssi > 35) {
+ new_lvl = CCK_PD_LV2;
+ } else if (dm_info->min_rssi > 20) {
+ if (dm_info->cck_fa_avg > 500)
+ new_lvl = CCK_PD_LV2;
+ else if (dm_info->cck_fa_avg < 250)
+ new_lvl = CCK_PD_LV1;
+ else
+ return;
+ } else {
+ new_lvl = CCK_PD_LV1;
+ }
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n",
+ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl);
+
+ if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl)
+ return;
+
+ dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
+ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl;
+
+ rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]);
+}
+EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
new file mode 100644
index 000000000000..09a45c1a4129
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW88XXA_H__
+#define __RTW88XXA_H__
+
+#include <asm/byteorder.h>
+#include "reg.h"
+
+struct rtw8821au_efuse {
+ u8 res4[48]; /* 0xd0 */
+ u8 vid[2]; /* 0x100 */
+ u8 pid[2];
+ u8 res8[3];
+ u8 mac_addr[ETH_ALEN]; /* 0x107 */
+ u8 res9[243];
+} __packed;
+
+struct rtw8812au_efuse {
+ u8 vid[2]; /* 0xd0 */
+ u8 pid[2]; /* 0xd2 */
+ u8 res0[3];
+ u8 mac_addr[ETH_ALEN]; /* 0xd7 */
+ u8 res1[291];
+} __packed;
+
+struct rtw88xxa_efuse {
+ __le16 rtl_id;
+ u8 res0[6]; /* 0x02 */
+ u8 usb_mode; /* 0x08 */
+ u8 res1[7]; /* 0x09 */
+
+ /* power index for four RF paths */
+ struct rtw_txpwr_idx txpwr_idx_table[4];
+
+ u8 channel_plan; /* 0xb8 */
+ u8 xtal_k;
+ u8 thermal_meter;
+ u8 iqk_lck;
+ u8 pa_type; /* 0xbc */
+ u8 lna_type_2g; /* 0xbd */
+ u8 res2;
+ u8 lna_type_5g; /* 0xbf */
+ u8 res3;
+ u8 rf_board_option; /* 0xc1 */
+ u8 rf_feature_option;
+ u8 rf_bt_setting;
+ u8 eeprom_version;
+ u8 eeprom_customer_id; /* 0xc5 */
+ u8 tx_bb_swing_setting_2g;
+ u8 tx_bb_swing_setting_5g;
+ u8 tx_pwr_calibrate_rate;
+ u8 rf_antenna_option; /* 0xc9 */
+ u8 rfe_option;
+ u8 country_code[2];
+ u8 res4[3];
+ union {
+ struct rtw8821au_efuse rtw8821au;
+ struct rtw8812au_efuse rtw8812au;
+ };
+} __packed;
+
+static_assert(sizeof(struct rtw88xxa_efuse) == 512);
+
+#define WLAN_BCN_DMA_TIME 0x02
+#define WLAN_TBTT_PROHIBIT 0x04
+#define WLAN_TBTT_HOLD_TIME 0x064
+#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
+ (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
+
+struct rtw_jaguar_phy_status_rpt {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
+ __le32 w6;
+} __packed;
+
+#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0)
+#define RTW_JGRPHY_W0_TRSW_A BIT(7)
+#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8)
+#define RTW_JGRPHY_W0_TRSW_B BIT(15)
+#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16)
+#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26)
+#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30)
+
+/* CCK: */
+#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0)
+#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8)
+#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13)
+#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16)
+/* OFDM: */
+#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0)
+#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */
+#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */
+#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30)
+
+#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0)
+#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1)
+#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2)
+#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */
+#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */
+#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24)
+
+#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0)
+/* Stream 1 and 2 RX EVM: */
+#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */
+#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */
+#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */
+
+#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */
+#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8)
+#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22)
+#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */
+
+#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */
+/* 8812a, stream 1 and 2 CSI: */
+#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8)
+#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16)
+/* 8814a: */
+#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */
+#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */
+#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24)
+#define RTW_JGRPHY_W5_TRSW_C BIT(31)
+
+#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0)
+#define RTW_JGRPHY_W6_TRSW_D BIT(7)
+#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */
+#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16)
+#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19)
+#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22)
+#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23)
+#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24)
+#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27)
+#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30)
+
+#define RF18_BW_MASK (BIT(11) | BIT(10))
+
+void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on);
+int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map);
+void rtw88xxa_power_off(struct rtw_dev *rtwdev,
+ const struct rtw_pwr_seq_cmd *const *enter_lps_flow);
+int rtw88xxa_power_on(struct rtw_dev *rtwdev);
+u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,
+ enum rtw_rf_path rf_path, u32 addr, u32 mask);
+void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_chan_idx);
+void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx));
+void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev);
+void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev);
+void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev,
+ u32 *macbb_backup,
+ const u32 *backup_macbb_reg,
+ u32 macbb_num);
+void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
+ const u32 *backup_afe_reg, u32 afe_num);
+void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev,
+ u32 *macbb_backup,
+ const u32 *backup_macbb_reg,
+ u32 macbb_num);
+void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev);
+bool rtw88xxa_iqk_finish(int average, int threshold,
+ int *x_temp, int *y_temp, int *x, int *y,
+ bool break_inner, bool break_outer);
+void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
+ void (*do_lck)(struct rtw_dev *rtwdev),
+ void (*do_iqk)(struct rtw_dev *rtwdev));
+void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl);
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c
index 1de93fc9efe9..90fc8a5fa89e 100644
--- a/drivers/net/wireless/realtek/rtw88/rx.c
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
@@ -234,10 +234,14 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
else
rx_status->bw = RATE_INFO_BW_20;
- rx_status->signal = pkt_stat->signal_power;
- for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
- rx_status->chains |= BIT(path);
- rx_status->chain_signal[path] = pkt_stat->rx_power[path];
+ if (pkt_stat->phy_status) {
+ rx_status->signal = pkt_stat->signal_power;
+ for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
+ rx_status->chains |= BIT(path);
+ rx_status->chain_signal[path] = pkt_stat->rx_power[path];
+ }
+ } else {
+ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
}
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index f0b06ed8f76d..799230eb5f16 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
- rtw_tx_fill_tx_desc(pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
}
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index dae7ca148865..6ed470dd6f22 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
}
}
-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
+void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
{
struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
bool more_data = false;
@@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE);
+ if (rtwdev->chip->old_datarate_fb_limit)
+ tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT);
+
tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) |
le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) |
le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) |
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index 3d544fd7f60f..d34cdeca16f1 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -44,6 +44,7 @@ struct rtw_tx_desc {
#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15)
#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17)
#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0)
+#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8)
#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24)
#define RTW_TX_DESC_W5_DATA_SHORT BIT(4)
#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5)
@@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
struct ieee80211_sta *sta,
struct sk_buff *skb);
-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
+void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index ba314d90ab3f..6fa3c37205f5 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -458,7 +458,7 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
skb_put_data(skb, buf, size);
skb_push(skb, chip->tx_pkt_desc_sz);
memset(skb->data, 0, chip->tx_pkt_desc_sz);
- rtw_tx_fill_tx_desc(pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
ret = rtw_usb_write_port(rtwdev, qsel, skb,
@@ -478,6 +478,7 @@ static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf,
pkt_info.tx_pkt_size = size;
pkt_info.qsel = TX_DESC_QSEL_BEACON;
pkt_info.offset = chip->tx_pkt_desc_sz;
+ pkt_info.ls = true;
return rtw_usb_write_data(rtwdev, &pkt_info, buf);
}
@@ -525,7 +526,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
ep = qsel_to_ep(rtwusb, pkt_info->qsel);
- rtw_tx_fill_tx_desc(pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
tx_data = rtw_usb_get_tx_data(skb);
tx_data->sn = pkt_info->sn;
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
index 8d140b94cb44..8ef59994c0db 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.c
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
@@ -961,16 +961,24 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
{
+ struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_addr_cam_entry *addr_cam =
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+ bool is_mld = sta ? sta->mlo : ieee80211_vif_is_mld(vif);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
+ u8 *mld_sma, *mld_tma, *mld_bssid;
h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
rtwvif_link->mac_id,
DCTLINFO_V2_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V2_C0_OP);
+ h2c->w2 = le32_encode_bits(is_mld, DCTLINFO_V2_W2_IS_MLD);
+ h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_IS_MLD);
+
h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0],
DCTLINFO_V2_W4_SEC_ENT0_KEYID) |
le32_encode_bits(addr_cam->sec_ent_keyid[1],
@@ -1036,4 +1044,47 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
DCTLINFO_V2_W4_SEC_KEY_ID);
h2c->m4 |= cpu_to_le32(DCTLINFO_V2_W4_SEC_KEY_ID);
}
+
+ if (!is_mld)
+ return;
+
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) {
+ mld_sma = rtwvif->mac_addr;
+ mld_tma = vif->cfg.ap_addr;
+ mld_bssid = vif->cfg.ap_addr;
+ } else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE && sta) {
+ mld_sma = rtwvif->mac_addr;
+ mld_tma = sta->addr;
+ mld_bssid = rtwvif->mac_addr;
+ } else {
+ return;
+ }
+
+ h2c->w8 = le32_encode_bits(mld_sma[0], DCTLINFO_V2_W8_MLD_SMA_0) |
+ le32_encode_bits(mld_sma[1], DCTLINFO_V2_W8_MLD_SMA_1) |
+ le32_encode_bits(mld_sma[2], DCTLINFO_V2_W8_MLD_SMA_2) |
+ le32_encode_bits(mld_sma[3], DCTLINFO_V2_W8_MLD_SMA_3);
+ h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL);
+
+ h2c->w9 = le32_encode_bits(mld_sma[4], DCTLINFO_V2_W9_MLD_SMA_4) |
+ le32_encode_bits(mld_sma[5], DCTLINFO_V2_W9_MLD_SMA_5) |
+ le32_encode_bits(mld_tma[0], DCTLINFO_V2_W9_MLD_TMA_0) |
+ le32_encode_bits(mld_tma[1], DCTLINFO_V2_W9_MLD_TMA_1);
+ h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL);
+
+ h2c->w10 = le32_encode_bits(mld_tma[2], DCTLINFO_V2_W10_MLD_TMA_2) |
+ le32_encode_bits(mld_tma[3], DCTLINFO_V2_W10_MLD_TMA_3) |
+ le32_encode_bits(mld_tma[4], DCTLINFO_V2_W10_MLD_TMA_4) |
+ le32_encode_bits(mld_tma[5], DCTLINFO_V2_W10_MLD_TMA_5);
+ h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL);
+
+ h2c->w11 = le32_encode_bits(mld_bssid[0], DCTLINFO_V2_W11_MLD_BSSID_0) |
+ le32_encode_bits(mld_bssid[1], DCTLINFO_V2_W11_MLD_BSSID_1) |
+ le32_encode_bits(mld_bssid[2], DCTLINFO_V2_W11_MLD_BSSID_2) |
+ le32_encode_bits(mld_bssid[3], DCTLINFO_V2_W11_MLD_BSSID_3);
+ h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL);
+
+ h2c->w12 = le32_encode_bits(mld_bssid[4], DCTLINFO_V2_W12_MLD_BSSID_4) |
+ le32_encode_bits(mld_bssid[5], DCTLINFO_V2_W12_MLD_BSSID_5);
+ h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL);
}
diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h
index a6f72edd30fe..3134ebf08825 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.h
+++ b/drivers/net/wireless/realtek/rtw89/cam.h
@@ -514,16 +514,28 @@ struct rtw89_h2c_dctlinfo_ud_v2 {
#define DCTLINFO_V2_W7_SEC_ENT7 GENMASK(23, 16)
#define DCTLINFO_V2_W7_SEC_ENT8 GENMASK(31, 24)
#define DCTLINFO_V2_W7_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W8_MLD_SMA_L_V1 GENMASK(31, 0)
+#define DCTLINFO_V2_W8_MLD_SMA_0 GENMASK(7, 0)
+#define DCTLINFO_V2_W8_MLD_SMA_1 GENMASK(15, 8)
+#define DCTLINFO_V2_W8_MLD_SMA_2 GENMASK(23, 16)
+#define DCTLINFO_V2_W8_MLD_SMA_3 GENMASK(31, 24)
#define DCTLINFO_V2_W8_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W9_MLD_SMA_H_V1 GENMASK(15, 0)
-#define DCTLINFO_V2_W9_MLD_TMA_L_V1 GENMASK(31, 16)
+#define DCTLINFO_V2_W9_MLD_SMA_4 GENMASK(7, 0)
+#define DCTLINFO_V2_W9_MLD_SMA_5 GENMASK(15, 8)
+#define DCTLINFO_V2_W9_MLD_TMA_0 GENMASK(23, 16)
+#define DCTLINFO_V2_W9_MLD_TMA_1 GENMASK(31, 24)
#define DCTLINFO_V2_W9_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W10_MLD_TMA_H_V1 GENMASK(31, 0)
+#define DCTLINFO_V2_W10_MLD_TMA_2 GENMASK(7, 0)
+#define DCTLINFO_V2_W10_MLD_TMA_3 GENMASK(15, 8)
+#define DCTLINFO_V2_W10_MLD_TMA_4 GENMASK(23, 16)
+#define DCTLINFO_V2_W10_MLD_TMA_5 GENMASK(31, 24)
#define DCTLINFO_V2_W10_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W11_MLD_TA_BSSID_L_V1 GENMASK(31, 0)
+#define DCTLINFO_V2_W11_MLD_BSSID_0 GENMASK(7, 0)
+#define DCTLINFO_V2_W11_MLD_BSSID_1 GENMASK(15, 8)
+#define DCTLINFO_V2_W11_MLD_BSSID_2 GENMASK(23, 16)
+#define DCTLINFO_V2_W11_MLD_BSSID_3 GENMASK(31, 24)
#define DCTLINFO_V2_W11_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W12_MLD_TA_BSSID_H_V1 GENMASK(15, 0)
+#define DCTLINFO_V2_W12_MLD_BSSID_4 GENMASK(7, 0)
+#define DCTLINFO_V2_W12_MLD_BSSID_5 GENMASK(15, 8)
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index ba6332da8019..fb9449930c40 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -10,6 +10,10 @@
#include "ps.h"
#include "util.h"
+static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_idx idx1,
+ enum rtw89_chanctx_idx idx2);
+
static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
u8 center_chan)
{
@@ -226,11 +230,15 @@ static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
void rtw89_entity_init(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
hal->entity_pause = false;
bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX);
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE);
+
+ INIT_LIST_HEAD(&mgnt->active_list);
+
rtw89_config_default_chandef(rtwdev);
}
@@ -272,6 +280,142 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
}
}
+static void rtw89_normalize_link_chanctx(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_vif_link *cur;
+
+ if (unlikely(!rtwvif_link->chanctx_assigned))
+ return;
+
+ cur = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (!cur || !cur->chanctx_assigned)
+ return;
+
+ if (cur == rtwvif_link)
+ return;
+
+ rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx);
+}
+
+const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
+ const char *caller_message,
+ u8 link_index)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
+ enum rtw89_chanctx_idx chanctx_idx;
+ enum rtw89_chanctx_idx roc_idx;
+ enum rtw89_entity_mode mode;
+ u8 role_index;
+
+ lockdep_assert_held(&rtwdev->mutex);
+
+ if (unlikely(link_index >= __RTW89_MLD_MAX_LINK_NUM)) {
+ WARN(1, "link index %u is invalid (max link inst num: %d)\n",
+ link_index, __RTW89_MLD_MAX_LINK_NUM);
+ goto dflt;
+ }
+
+ mode = rtw89_get_entity_mode(rtwdev);
+ switch (mode) {
+ case RTW89_ENTITY_MODE_SCC_OR_SMLD:
+ case RTW89_ENTITY_MODE_MCC:
+ role_index = 0;
+ break;
+ case RTW89_ENTITY_MODE_MCC_PREPARE:
+ role_index = 1;
+ break;
+ default:
+ WARN(1, "Invalid ent mode: %d\n", mode);
+ goto dflt;
+ }
+
+ chanctx_idx = mgnt->chanctx_tbl[role_index][link_index];
+ if (chanctx_idx == RTW89_CHANCTX_IDLE)
+ goto dflt;
+
+ roc_idx = atomic_read(&hal->roc_chanctx_idx);
+ if (roc_idx != RTW89_CHANCTX_IDLE) {
+ /* ROC is ongoing (given ROC runs on RTW89_ROC_BY_LINK_INDEX).
+ * If @link_index is the same as RTW89_ROC_BY_LINK_INDEX, get
+ * the ongoing ROC chanctx.
+ */
+ if (link_index == RTW89_ROC_BY_LINK_INDEX)
+ chanctx_idx = roc_idx;
+ }
+
+ return rtw89_chan_get(rtwdev, chanctx_idx);
+
+dflt:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "%s (%s): prefetch NULL on link index %u\n",
+ __func__, caller_message ?: "", link_index);
+
+ return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+}
+EXPORT_SYMBOL(__rtw89_mgnt_chan_get);
+
+static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
+ struct rtw89_vif_link *link;
+ struct rtw89_vif *role;
+ u8 pos = 0;
+ int i, j;
+
+ lockdep_assert_held(&rtwdev->mutex);
+
+ for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++)
+ mgnt->active_roles[i] = NULL;
+
+ for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) {
+ for (j = 0; j < __RTW89_MLD_MAX_LINK_NUM; j++)
+ mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE;
+ }
+
+ /* To be consistent with legacy behavior, expect the first active role
+ * which uses RTW89_CHANCTX_0 to put at position 0, and make its first
+ * link instance take RTW89_CHANCTX_0. (normalizing)
+ */
+ list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
+ for (i = 0; i < role->links_inst_valid_num; i++) {
+ link = rtw89_vif_get_link_inst(role, i);
+ if (!link || !link->chanctx_assigned)
+ continue;
+
+ if (link->chanctx_idx == RTW89_CHANCTX_0) {
+ rtw89_normalize_link_chanctx(rtwdev, link);
+
+ list_del(&role->mgnt_entry);
+ list_add(&role->mgnt_entry, &mgnt->active_list);
+ break;
+ }
+ }
+ }
+
+ list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
+ if (unlikely(pos >= RTW89_MAX_INTERFACE_NUM)) {
+ rtw89_warn(rtwdev,
+ "%s: active roles are over max iface num\n",
+ __func__);
+ break;
+ }
+
+ for (i = 0; i < role->links_inst_valid_num; i++) {
+ link = rtw89_vif_get_link_inst(role, i);
+ if (!link || !link->chanctx_assigned)
+ continue;
+
+ mgnt->chanctx_tbl[pos][i] = link->chanctx_idx;
+ }
+
+ mgnt->active_roles[pos++] = role;
+ }
+}
+
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
{
DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_CHANCTX) = {};
@@ -298,9 +442,14 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
set_bit(RTW89_CHANCTX_0, recalc_map);
fallthrough;
case 1:
- mode = RTW89_ENTITY_MODE_SCC;
+ mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
break;
case 2 ... NUM_OF_RTW89_CHANCTX:
+ if (w.active_roles == 1) {
+ mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
+ break;
+ }
+
if (w.active_roles != NUM_OF_RTW89_MCC_ROLES) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"unhandled ent: %d chanctxs %d roles\n",
@@ -327,6 +476,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
rtw89_assign_entity_chan(rtwdev, idx, &chan);
}
+ rtw89_entity_recalc_mgnt_roles(rtwdev);
+
if (hal->entity_pause)
return rtw89_get_entity_mode(rtwdev);
@@ -716,6 +867,7 @@ struct rtw89_mcc_fill_role_selector {
};
static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
+static_assert(RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES);
static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role,
@@ -745,14 +897,18 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_mcc_fill_role_selector sel = {};
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
int ret;
+ int i;
- rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (!rtw89_vif_is_active_role(rtwvif))
- continue;
+ for (i = 0; i < NUM_OF_RTW89_MCC_ROLES; i++) {
+ rtwvif = mgnt->active_roles[i];
+ if (!rtwvif)
+ break;
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
@@ -760,14 +916,7 @@ static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
continue;
}
- if (sel.bind_vif[rtwvif_link->chanctx_idx]) {
- rtw89_warn(rtwdev,
- "MCC skip extra vif <macid %d> on chanctx[%d]\n",
- rtwvif_link->mac_id, rtwvif_link->chanctx_idx);
- continue;
- }
-
- sel.bind_vif[rtwvif_link->chanctx_idx] = rtwvif_link;
+ sel.bind_vif[i] = rtwvif_link;
}
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@@ -2501,12 +2650,18 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_entity_weight w = {};
rtwvif_link->chanctx_idx = cfg->idx;
rtwvif_link->chanctx_assigned = true;
cfg->ref_count++;
+ if (list_empty(&rtwvif->mgnt_entry))
+ list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list);
+
if (cfg->idx == RTW89_CHANCTX_0)
goto out;
@@ -2526,6 +2681,7 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_chanctx_idx roll;
enum rtw89_entity_mode cur;
@@ -2536,6 +2692,9 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
rtwvif_link->chanctx_assigned = false;
cfg->ref_count--;
+ if (!rtw89_vif_is_active_role(rtwvif))
+ list_del_init(&rtwvif->mgnt_entry);
+
if (cfg->ref_count != 0)
goto out;
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index 74de13a2e7da..2eb31dff2083 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -101,6 +101,14 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_pause_reasons rsn);
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev);
+
+const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
+ const char *caller_message,
+ u8 link_index);
+
+#define rtw89_mgnt_chan_get(rtwdev, link_index) \
+ __rtw89_mgnt_chan_get(rtwdev, __func__, link_index)
+
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 989e6e882c6e..ced42f9d297d 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -2507,6 +2507,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
if (ver->fcxmreg == 7) {
sz = struct_size(v7, regs, n);
v7 = kmalloc(sz, GFP_KERNEL);
+ if (!v7)
+ return;
v7->type = RPT_EN_MREG;
v7->fver = ver->fcxmreg;
v7->len = n;
@@ -2521,6 +2523,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
} else {
sz = struct_size(v1, regs, n);
v1 = kmalloc(sz, GFP_KERNEL);
+ if (!v1)
+ return;
v1->fver = ver->fcxmreg;
v1->reg_num = n;
memcpy(v1->regs, chip->mon_reg, flex_array_size(v1, regs, n));
@@ -3695,6 +3699,7 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc;
struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
@@ -3853,7 +3858,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype);
break;
case BTC_CXP_OFFE_2GBWMIXB:
- _slot_set(btc, CXST_E2G, 0, 0xea5a5555, SLOT_MIX);
+ if (a2dp->exist)
+ _slot_set(btc, CXST_E2G, 0, cxtbl[2], SLOT_MIX);
+ else
+ _slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_MIX);
_slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
break;
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index bba5bde95bb4..e5b2968c1431 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -192,13 +192,13 @@ static const struct ieee80211_iface_combination rtw89_iface_combs[] = {
{
.limits = rtw89_iface_limits,
.n_limits = ARRAY_SIZE(rtw89_iface_limits),
- .max_interfaces = 2,
+ .max_interfaces = RTW89_MAX_INTERFACE_NUM,
.num_different_channels = 1,
},
{
.limits = rtw89_iface_limits_mcc,
.n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc),
- .max_interfaces = 2,
+ .max_interfaces = RTW89_MAX_INTERFACE_NUM,
.num_different_channels = 2,
},
};
@@ -341,84 +341,47 @@ void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
rtw89_chan_create(chan, center_chan, channel->hw_value, band, bandwidth);
}
-void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
+static void __rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
{
- struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_chan *chan;
- enum rtw89_chanctx_idx chanctx_idx;
- enum rtw89_chanctx_idx roc_idx;
- enum rtw89_phy_idx phy_idx;
- enum rtw89_entity_mode mode;
bool entity_active;
- mode = rtw89_get_entity_mode(rtwdev);
- switch (mode) {
- case RTW89_ENTITY_MODE_SCC:
- case RTW89_ENTITY_MODE_MCC:
- chanctx_idx = RTW89_CHANCTX_0;
- break;
- case RTW89_ENTITY_MODE_MCC_PREPARE:
- chanctx_idx = RTW89_CHANCTX_1;
- break;
- default:
- WARN(1, "Invalid ent mode: %d\n", mode);
+ entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
+ if (!entity_active)
return;
- }
- roc_idx = atomic_read(&hal->roc_chanctx_idx);
- if (roc_idx != RTW89_CHANCTX_IDLE)
- chanctx_idx = roc_idx;
+ chip->ops->set_txpwr(rtwdev, chan, phy_idx);
+}
- phy_idx = RTW89_PHY_0;
+void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chan *chan;
- entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
- if (!entity_active)
+ chan = rtw89_mgnt_chan_get(rtwdev, 0);
+ __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_0);
+
+ if (!rtwdev->support_mlo)
return;
- chan = rtw89_chan_get(rtwdev, chanctx_idx);
- chip->ops->set_txpwr(rtwdev, chan, phy_idx);
+ chan = rtw89_mgnt_chan_get(rtwdev, 1);
+ __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1);
}
-int rtw89_set_channel(struct rtw89_dev *rtwdev)
+static void __rtw89_set_channel(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_mac_idx mac_idx,
+ enum rtw89_phy_idx phy_idx)
{
- struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan_rcd *chan_rcd;
- const struct rtw89_chan *chan;
- enum rtw89_chanctx_idx chanctx_idx;
- enum rtw89_chanctx_idx roc_idx;
- enum rtw89_mac_idx mac_idx;
- enum rtw89_phy_idx phy_idx;
struct rtw89_channel_help_params bak;
- enum rtw89_entity_mode mode;
bool entity_active;
- mode = rtw89_entity_recalc(rtwdev);
- switch (mode) {
- case RTW89_ENTITY_MODE_SCC:
- case RTW89_ENTITY_MODE_MCC:
- chanctx_idx = RTW89_CHANCTX_0;
- break;
- case RTW89_ENTITY_MODE_MCC_PREPARE:
- chanctx_idx = RTW89_CHANCTX_1;
- break;
- default:
- WARN(1, "Invalid ent mode: %d\n", mode);
- return -EINVAL;
- }
-
- roc_idx = atomic_read(&hal->roc_chanctx_idx);
- if (roc_idx != RTW89_CHANCTX_IDLE)
- chanctx_idx = roc_idx;
-
- mac_idx = RTW89_MAC_0;
- phy_idx = RTW89_PHY_0;
-
entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
- chan = rtw89_chan_get(rtwdev, chanctx_idx);
- chan_rcd = rtw89_chan_rcd_get(rtwdev, chanctx_idx);
+ chan_rcd = rtw89_chan_rcd_get_by_chan(chan);
rtw89_chip_set_channel_prepare(rtwdev, &bak, chan, mac_idx, phy_idx);
@@ -434,6 +397,28 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev)
}
rtw89_set_entity_state(rtwdev, phy_idx, true);
+}
+
+int rtw89_set_channel(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chan *chan;
+ enum rtw89_entity_mode mode;
+
+ mode = rtw89_entity_recalc(rtwdev);
+ if (mode < 0 || mode >= NUM_OF_RTW89_ENTITY_MODE) {
+ WARN(1, "Invalid ent mode: %d\n", mode);
+ return -EINVAL;
+ }
+
+ chan = rtw89_mgnt_chan_get(rtwdev, 0);
+ __rtw89_set_channel(rtwdev, chan, RTW89_MAC_0, RTW89_PHY_0);
+
+ if (!rtwdev->support_mlo)
+ return 0;
+
+ chan = rtw89_mgnt_chan_get(rtwdev, 1);
+ __rtw89_set_channel(rtwdev, chan, RTW89_MAC_1, RTW89_PHY_1);
+
return 0;
}
@@ -939,8 +924,10 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
struct sk_buff *skb = tx_req->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct rtw89_addr_cam_entry *addr_cam;
enum rtw89_core_tx_type tx_type;
enum btc_pkt_type pkt_type;
+ bool upd_wlan_hdr = false;
bool is_bmc;
u16 seq;
@@ -948,6 +935,11 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) {
tx_type = rtw89_core_get_tx_type(rtwdev, skb);
tx_req->tx_type = tx_type;
+
+ addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link,
+ tx_req->rtwsta_link);
+ if (addr_cam->valid)
+ upd_wlan_hdr = true;
}
is_bmc = (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1));
@@ -957,6 +949,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
desc_info->is_bmc = is_bmc;
desc_info->wd_page = true;
desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM;
+ desc_info->upd_wlan_hdr = upd_wlan_hdr;
switch (tx_req->tx_type) {
case RTW89_CORE_TX_TYPE_MGMT:
@@ -1355,6 +1348,13 @@ static __le32 rtw89_build_txwd_body5_v2(struct rtw89_tx_desc_info *desc_info)
return cpu_to_le32(dword);
}
+static __le32 rtw89_build_txwd_body6_v2(struct rtw89_tx_desc_info *desc_info)
+{
+ u32 dword = FIELD_PREP(BE_TXD_BODY6_UPD_WLAN_HDR, desc_info->upd_wlan_hdr);
+
+ return cpu_to_le32(dword);
+}
+
static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) |
@@ -1418,6 +1418,7 @@ void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev,
txwd_body->dword4 = rtw89_build_txwd_body4_v2(desc_info);
txwd_body->dword5 = rtw89_build_txwd_body5_v2(desc_info);
}
+ txwd_body->dword6 = rtw89_build_txwd_body6_v2(desc_info);
txwd_body->dword7 = rtw89_build_txwd_body7_v2(desc_info);
if (!desc_info->en_wd_info)
@@ -1858,32 +1859,58 @@ static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev,
phy_ppdu);
}
-static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev,
- u8 desc_info_gi,
- bool rx_status, bool eht)
+static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev,
+ u8 desc_info_gi,
+ bool rx_status)
{
switch (desc_info_gi) {
case RTW89_GILTF_SGI_4XHE08:
case RTW89_GILTF_2XHE08:
case RTW89_GILTF_1XHE08:
- return eht ? NL80211_RATE_INFO_EHT_GI_0_8 :
- NL80211_RATE_INFO_HE_GI_0_8;
+ return NL80211_RATE_INFO_HE_GI_0_8;
case RTW89_GILTF_2XHE16:
case RTW89_GILTF_1XHE16:
- return eht ? NL80211_RATE_INFO_EHT_GI_1_6 :
- NL80211_RATE_INFO_HE_GI_1_6;
+ return NL80211_RATE_INFO_HE_GI_1_6;
case RTW89_GILTF_LGI_4XHE32:
- return eht ? NL80211_RATE_INFO_EHT_GI_3_2 :
- NL80211_RATE_INFO_HE_GI_3_2;
+ return NL80211_RATE_INFO_HE_GI_3_2;
default:
rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi);
if (rx_status)
- return eht ? NL80211_RATE_INFO_EHT_GI_3_2 :
- NL80211_RATE_INFO_HE_GI_3_2;
+ return NL80211_RATE_INFO_HE_GI_3_2;
return U8_MAX;
}
}
+static u8 rtw89_rxdesc_to_nl_eht_gi(struct rtw89_dev *rtwdev,
+ u8 desc_info_gi,
+ bool rx_status)
+{
+ switch (desc_info_gi) {
+ case RTW89_GILTF_SGI_4XHE08:
+ case RTW89_GILTF_2XHE08:
+ case RTW89_GILTF_1XHE08:
+ return NL80211_RATE_INFO_EHT_GI_0_8;
+ case RTW89_GILTF_2XHE16:
+ case RTW89_GILTF_1XHE16:
+ return NL80211_RATE_INFO_EHT_GI_1_6;
+ case RTW89_GILTF_LGI_4XHE32:
+ return NL80211_RATE_INFO_EHT_GI_3_2;
+ default:
+ rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi);
+ if (rx_status)
+ return NL80211_RATE_INFO_EHT_GI_3_2;
+ return U8_MAX;
+ }
+}
+
+static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev,
+ u8 desc_info_gi,
+ bool rx_status, bool eht)
+{
+ return eht ? rtw89_rxdesc_to_nl_eht_gi(rtwdev, desc_info_gi, rx_status) :
+ rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info_gi, rx_status);
+}
+
static
bool rtw89_check_rx_statu_gi_match(struct ieee80211_rx_status *status, u8 gi_ltf,
bool eht)
@@ -3162,9 +3189,10 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
- rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, RTW89_ROC_BY_LINK_INDEX);
if (unlikely(!rtwvif_link)) {
- rtw89_err(rtwdev, "roc start: find no link on HW-0\n");
+ rtw89_err(rtwdev, "roc start: find no link on HW-%u\n",
+ RTW89_ROC_BY_LINK_INDEX);
return;
}
@@ -3217,9 +3245,10 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
- rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, RTW89_ROC_BY_LINK_INDEX);
if (unlikely(!rtwvif_link)) {
- rtw89_err(rtwdev, "roc end: find no link on HW-0\n");
+ rtw89_err(rtwdev, "roc end: find no link on HW-%u\n",
+ RTW89_ROC_BY_LINK_INDEX);
return;
}
@@ -4818,11 +4847,20 @@ static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
rtwdev->hal.support_cckpd =
!(rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV) &&
!(rtwdev->chip->chip_id == RTL8852B && rtwdev->hal.cv <= CHIP_CAV);
rtwdev->hal.support_igi =
rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV;
+
+ if (test_bit(RTW89_QUIRK_THERMAL_PROT_120C, rtwdev->quirks))
+ rtwdev->hal.thermal_prot_th = chip->thermal_th[1];
+ else if (test_bit(RTW89_QUIRK_THERMAL_PROT_110C, rtwdev->quirks))
+ rtwdev->hal.thermal_prot_th = chip->thermal_th[0];
+ else
+ rtwdev->hal.thermal_prot_th = 0;
}
static void rtw89_core_setup_rfe_parms(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 38df161bfd35..5ad32eacd0d5 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1162,6 +1162,7 @@ struct rtw89_tx_desc_info {
bool er_cap;
bool stbc;
bool ldpc;
+ bool upd_wlan_hdr;
};
struct rtw89_core_tx_request {
@@ -3427,6 +3428,8 @@ enum rtw89_roc_state {
RTW89_ROC_MGMT,
};
+#define RTW89_ROC_BY_LINK_INDEX 0
+
struct rtw89_roc {
struct ieee80211_channel chan;
struct delayed_work roc_work;
@@ -4244,6 +4247,7 @@ struct rtw89_chip_info {
u8 wde_qempty_acq_grpnum;
u8 wde_qempty_mgq_grpsel;
u32 rf_base_addr[2];
+ u8 thermal_th[2];
u8 support_macid_num;
u8 support_link_num;
u8 support_chanctx_num;
@@ -4512,11 +4516,14 @@ enum rtw89_fw_mss_dev_type {
};
struct rtw89_fw_secure {
- bool secure_boot;
+ bool secure_boot: 1;
+ bool can_mss_v1: 1;
+ bool can_mss_v0: 1;
u32 sb_sel_mgn;
u8 mss_dev_type;
u8 mss_cust_idx;
u8 mss_key_num;
+ u8 mss_idx; /* v0 */
};
struct rtw89_fw_info {
@@ -4562,7 +4569,7 @@ enum rtw89_sar_subband {
RTW89_SAR_2GHZ_SUBBAND,
RTW89_SAR_5GHZ_SUBBAND_1_2, /* U-NII-1 and U-NII-2 */
RTW89_SAR_5GHZ_SUBBAND_2_E, /* U-NII-2-Extended */
- RTW89_SAR_5GHZ_SUBBAND_3, /* U-NII-3 */
+ RTW89_SAR_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */
RTW89_SAR_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */
RTW89_SAR_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */
RTW89_SAR_6GHZ_SUBBAND_6, /* U-NII-6 */
@@ -4624,7 +4631,7 @@ enum rtw89_chanctx_changes {
};
enum rtw89_entity_mode {
- RTW89_ENTITY_MODE_SCC,
+ RTW89_ENTITY_MODE_SCC_OR_SMLD,
RTW89_ENTITY_MODE_MCC_PREPARE,
RTW89_ENTITY_MODE_MCC,
@@ -4633,6 +4640,16 @@ enum rtw89_entity_mode {
RTW89_ENTITY_MODE_UNHANDLED = -ESRCH,
};
+#define RTW89_MAX_INTERFACE_NUM 2
+
+/* only valid when running with chanctx_ops */
+struct rtw89_entity_mgnt {
+ struct list_head active_list;
+ struct rtw89_vif *active_roles[RTW89_MAX_INTERFACE_NUM];
+ enum rtw89_chanctx_idx chanctx_tbl[RTW89_MAX_INTERFACE_NUM]
+ [__RTW89_MLD_MAX_LINK_NUM];
+};
+
struct rtw89_chanctx {
struct cfg80211_chan_def chandef;
struct rtw89_chan chan;
@@ -4651,8 +4668,12 @@ struct rtw89_edcca_bak {
enum rtw89_dm_type {
RTW89_DM_DYNAMIC_EDCCA,
+ RTW89_DM_THERMAL_PROTECT,
};
+#define RTW89_THERMAL_PROT_LV_MAX 5
+#define RTW89_THERMAL_PROT_STEP 19 /* -19% for each level */
+
struct rtw89_hal {
u32 rx_fltr;
u8 cv;
@@ -4676,9 +4697,13 @@ struct rtw89_hal {
bool entity_active[RTW89_PHY_MAX];
bool entity_pause;
enum rtw89_entity_mode entity_mode;
+ struct rtw89_entity_mgnt entity_mgnt;
struct rtw89_edcca_bak edcca_bak;
u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
+
+ u8 thermal_prot_th;
+ u8 thermal_prot_lv; /* 0 ~ RTW89_THERMAL_PROT_LV_MAX */
};
#define RTW89_MAX_MAC_ID_NUM 128
@@ -4711,10 +4736,22 @@ enum rtw89_flags {
enum rtw89_quirks {
RTW89_QUIRK_PCI_BER,
+ RTW89_QUIRK_THERMAL_PROT_120C,
+ RTW89_QUIRK_THERMAL_PROT_110C,
NUM_OF_RTW89_QUIRKS,
};
+enum rtw89_custid {
+ RTW89_CUSTID_NONE,
+ RTW89_CUSTID_ACER,
+ RTW89_CUSTID_AMD,
+ RTW89_CUSTID_ASUS,
+ RTW89_CUSTID_DELL,
+ RTW89_CUSTID_HP,
+ RTW89_CUSTID_LENOVO,
+};
+
enum rtw89_pkt_drop_sel {
RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
RTW89_PKT_DROP_SEL_MACID_BK_ONCE,
@@ -4751,6 +4788,7 @@ DECLARE_EWMA(thermal, 4, 4);
struct rtw89_phy_stat {
struct ewma_thermal avg_thermal[RF_PATH_MAX];
+ u8 last_thermal_max;
struct ewma_rssi bcn_rssi;
struct rtw89_pkt_stat cur_pkt_stat;
struct rtw89_pkt_stat last_pkt_stat;
@@ -4793,13 +4831,17 @@ enum rtw89_rfk_chs_nrs {
RTW89_RFK_CHS_NR = __RTW89_RFK_CHS_NR_V1,
};
-struct rtw89_rfk_mcc_info {
+struct rtw89_rfk_mcc_info_data {
u8 ch[RTW89_RFK_CHS_NR];
u8 band[RTW89_RFK_CHS_NR];
u8 bw[RTW89_RFK_CHS_NR];
u8 table_idx;
};
+struct rtw89_rfk_mcc_info {
+ struct rtw89_rfk_mcc_info_data data[2];
+};
+
#define RTW89_IQK_CHS_NR 2
#define RTW89_IQK_PATH_NR 4
@@ -4904,6 +4946,7 @@ struct rtw89_agc_gaincode_set {
#define IGI_RSSI_TH_NUM 5
#define FA_TH_NUM 4
+#define TIA_LNA_OP1DB_NUM 8
#define LNA_GAIN_NUM 7
#define TIA_GAIN_NUM 2
struct rtw89_dig_info {
@@ -5511,6 +5554,7 @@ struct rtw89_dev {
struct rtw89_efuse efuse;
struct rtw89_traffic_stats stats;
struct rtw89_rfe_data *rfe_data;
+ enum rtw89_custid custid;
/* ensures exclusive access from mac80211 callbacks */
struct mutex mutex;
@@ -5613,6 +5657,7 @@ struct rtw89_dev {
struct rtw89_vif {
struct rtw89_dev *rtwdev;
struct list_head list;
+ struct list_head mgnt_entry;
u8 mac_addr[ETH_ALEN];
__be32 ip_addr;
@@ -6368,6 +6413,15 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
}
static inline
+const struct rtw89_chan_rcd *rtw89_chan_rcd_get_by_chan(const struct rtw89_chan *chan)
+{
+ const struct rtw89_chanctx *chanctx =
+ container_of_const(chan, struct rtw89_chanctx, chan);
+
+ return &chanctx->rcd;
+}
+
+static inline
const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev)
{
struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 74b0c722a5b8..6abd88fa80ba 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -3672,14 +3672,19 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_rx_rate_cnt_info *info;
+ struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_hw_rate first_rate;
u8 rssi;
int i;
rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi);
- seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
- stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv,
+ seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d",
+ stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv);
+ if (hal->thermal_prot_lv)
+ seq_printf(m, ", duty: %d%%",
+ 100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP);
+ seq_printf(m, "), RX: %u [%u] Mbps (lv: %d)\n",
stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv);
seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr,
RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic);
@@ -3886,6 +3891,7 @@ static const struct rtw89_disabled_dm_info {
const char *name;
} rtw89_disabled_dm_infos[] = {
DM_INFO(DYNAMIC_EDCCA),
+ DM_INFO(THERMAL_PROTECT),
};
static int
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c
index e1236079a84a..6c6c763510af 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse.c
@@ -11,11 +11,38 @@
#define EF_CV_MASK GENMASK(7, 4)
#define EF_CV_INV 15
+#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
+#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
+#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
+#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
+
+#define EFUSE_EXTERNALPN_ADDR_AX 0x5EC
+#define EFUSE_CUSTOMER_ADDR_AX 0x5ED
+#define EFUSE_SERIALNUM_ADDR_AX 0x5ED
+
+#define EFUSE_B1_EXTERNALPN_MASK GENMASK(7, 0)
+#define EFUSE_B2_CUSTOMER_MASK GENMASK(3, 0)
+#define EFUSE_B2_SERIALNUM_MASK GENMASK(6, 4)
+
+#define OTP_KEY_INFO_NUM 2
+
+static const u8 otp_key_info_externalPN[OTP_KEY_INFO_NUM] = {0x0, 0x0};
+static const u8 otp_key_info_customer[OTP_KEY_INFO_NUM] = {0x0, 0x1};
+static const u8 otp_key_info_serialNum[OTP_KEY_INFO_NUM] = {0x0, 0x1};
+
enum rtw89_efuse_bank {
RTW89_EFUSE_BANK_WIFI,
RTW89_EFUSE_BANK_BT,
};
+enum rtw89_efuse_mss_dev_type {
+ MSS_DEV_TYPE_FWSEC_DEF = 0xF,
+ MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
+ MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
+ MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
+ MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
+};
+
static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
enum rtw89_efuse_bank bank)
{
@@ -354,3 +381,126 @@ int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
return 0;
}
EXPORT_SYMBOL(rtw89_read_efuse_ver);
+
+static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
+{
+ switch (mss_dev_type) {
+ case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
+ mss_dev_type = 0x0;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
+ mss_dev_type = 0x1;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
+ mss_dev_type = 0x2;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
+ mss_dev_type = 0x3;
+ break;
+ case MSS_DEV_TYPE_FWSEC_DEF:
+ mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
+ break;
+ default:
+ rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
+ mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
+ break;
+ }
+
+ return mss_dev_type;
+}
+
+int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 mss_dev_type;
+
+ if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) {
+ mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB;
+ sec->mss_cust_idx = 0;
+ sec->mss_key_num = 0;
+
+ goto mss_dev_type;
+ }
+
+ mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
+ sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
+ u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
+ sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
+
+mss_dev_type:
+ sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
+ if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
+ rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
+ return -ENOENT;
+ }
+
+ sec->can_mss_v1 = true;
+
+ return 0;
+}
+
+static
+int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 externalPN;
+ u8 serialNum;
+ u8 customer;
+ u8 i;
+
+ externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK);
+ customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK);
+ serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK);
+
+ for (i = 0; i < OTP_KEY_INFO_NUM; i++) {
+ if (externalPN == otp_key_info_externalPN[i] &&
+ customer == otp_key_info_customer[i] &&
+ serialNum == otp_key_info_serialNum[i]) {
+ sec->mss_idx = i;
+ sec->can_mss_v0 = true;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX;
+ u32 sec_size = 2;
+ u8 sec_map[2];
+ u8 b1, b2;
+ int ret;
+
+ ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map,
+ sec_addr, sec_size, false);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to dump secsel map\n");
+ return ret;
+ }
+
+ b1 = sec_map[0];
+ b2 = sec_map[1];
+
+ if (b1 == 0xFF && b2 == 0xFF)
+ return 0;
+
+ rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2);
+ rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
+ if (!sec->can_mss_v1 && !sec->can_mss_v0)
+ goto out;
+
+ sec->secure_boot = true;
+
+out:
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ "MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n",
+ sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1,
+ sec->mss_dev_type, sec->mss_cust_idx,
+ sec->mss_key_num, sec->mss_idx);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h
index 72416f56a071..a96fc1044791 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.h
+++ b/drivers/net/wireless/realtek/rtw89/efuse.h
@@ -23,6 +23,8 @@ int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev);
int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle);
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv);
+int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2);
+int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev);
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/efuse_be.c b/drivers/net/wireless/realtek/rtw89/efuse_be.c
index 0be26d5fdf7c..64768923b0f0 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse_be.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse_be.c
@@ -8,11 +8,7 @@
#include "reg.h"
#define EFUSE_EXTERNALPN_ADDR_BE 0x1580
-#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
-#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
#define EFUSE_SERIALNUM_ADDR_BE 0x1581
-#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
-#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
#define EFUSE_SB_CRYP_SEL_ADDR 0x1582
#define EFUSE_SB_CRYP_SEL_SIZE 2
#define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF
@@ -20,14 +16,6 @@
#define EFUSE_SEC_BE_START 0x1580
#define EFUSE_SEC_BE_SIZE 4
-enum rtw89_efuse_mss_dev_type {
- MSS_DEV_TYPE_FWSEC_DEF = 0xF,
- MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
- MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
- MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
- MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
-};
-
static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = {
0x8000100, 0xC000180
};
@@ -477,33 +465,6 @@ static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel)
return sb_cryp_sel_v + low_bit;
}
-static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
-{
- switch (mss_dev_type) {
- case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
- mss_dev_type = 0x0;
- break;
- case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
- mss_dev_type = 0x1;
- break;
- case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
- mss_dev_type = 0x2;
- break;
- case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
- mss_dev_type = 0x3;
- break;
- case MSS_DEV_TYPE_FWSEC_DEF:
- mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
- break;
- default:
- rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
- mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
- break;
- }
-
- return mss_dev_type;
-}
-
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
@@ -511,7 +472,6 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
u32 sec_size = EFUSE_SEC_BE_SIZE;
u16 sb_cryp_sel, sb_cryp_sel_idx;
u8 sec_map[EFUSE_SEC_BE_SIZE];
- u8 mss_dev_type;
u8 b1, b2;
int ret;
@@ -538,16 +498,9 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr];
b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr];
- mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
- sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
- u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
- sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
-
- sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
- if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
- rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
+ ret = rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
+ if (ret)
goto out;
- }
sec->secure_boot = true;
@@ -559,4 +512,3 @@ out:
return 0;
}
-EXPORT_SYMBOL(rtw89_efuse_read_fw_secure_be);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 2c2fdf21f065..2191c037d72e 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -56,6 +56,11 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
struct sk_buff *skb);
static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
struct rtw89_wait_info *wait, unsigned int cond);
+static int __parse_security_section(struct rtw89_dev *rtwdev,
+ struct rtw89_fw_bin_info *info,
+ struct rtw89_fw_hdr_section_info *section_info,
+ const void *content,
+ u32 *mssc_len);
static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
bool header)
@@ -124,13 +129,16 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
struct rtw89_fw_bin_info *info)
{
const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_hdr_section_info *section_info;
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
const struct rtw89_fw_hdr_section *section;
const u8 *fw_end = fw + len;
const u8 *bin;
u32 base_hdr_len;
- u32 mssc_len = 0;
+ u32 mssc_len;
+ int ret;
u32 i;
if (!info)
@@ -139,6 +147,7 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM);
base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
+ info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE);
if (info->dynamic_hdr_en) {
info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
@@ -161,26 +170,47 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section = &fw_hdr->sections[i];
section_info->type =
le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE);
- if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
- section_info->mssc =
- le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
- mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
- } else {
- section_info->mssc = 0;
- }
-
section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE);
+
if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM))
section_info->len += FWDL_SECTION_CHKSUM_LEN;
section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL);
section_info->dladdr =
le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff;
section_info->addr = bin;
- bin += section_info->len;
+
+ if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
+ section_info->mssc =
+ le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
+
+ ret = __parse_security_section(rtwdev, info, section_info,
+ bin, &mssc_len);
+ if (ret)
+ return ret;
+
+ if (sec->secure_boot && chip->chip_id == RTL8852B)
+ section_info->len_override = 960;
+ } else {
+ section_info->mssc = 0;
+ mssc_len = 0;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n",
+ i, section_info->type, section_info->len,
+ section_info->mssc, mssc_len, bin - fw);
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n",
+ section_info->ignore, section_info->key_addr,
+ section_info->key_addr ?
+ section_info->key_addr - section_info->addr : 0,
+ section_info->key_len, section_info->key_idx);
+
+ bin += section_info->len + mssc_len;
section_info++;
}
- if (fw_end != bin + mssc_len) {
+ if (fw_end != bin) {
rtw89_err(rtwdev, "[ERR]fw bin size\n");
return -EINVAL;
}
@@ -235,7 +265,6 @@ static int __get_mssc_key_idx(struct rtw89_dev *rtwdev,
static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
- const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
@@ -318,18 +347,15 @@ ignore:
static int __parse_security_section(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
- const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
int ret;
- section_info->mssc =
- le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
-
- if (section_info->mssc == FORMATTED_MSSC) {
+ if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) {
ret = __parse_formatted_mssc(rtwdev, info, section_info,
- section, content, mssc_len);
+ content, mssc_len);
if (ret)
return -EINVAL;
} else {
@@ -337,6 +363,14 @@ static int __parse_security_section(struct rtw89_dev *rtwdev,
if (info->dsp_checksum)
*mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN;
+ if (sec->secure_boot) {
+ if (sec->mss_idx >= section_info->mssc)
+ return -EFAULT;
+ section_info->key_addr = content + section_info->len +
+ sec->mss_idx * FWDL_SECURITY_SIGLEN;
+ section_info->key_len = FWDL_SECURITY_SIGLEN;
+ }
+
info->secure_section_exist = true;
}
@@ -361,6 +395,7 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM);
base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
+ info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE);
if (info->dynamic_hdr_en) {
info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
@@ -394,8 +429,11 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section_info->addr = bin;
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
+ section_info->mssc =
+ le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
+
ret = __parse_security_section(rtwdev, info, section_info,
- section, bin, &mssc_len);
+ bin, &mssc_len);
if (ret)
return ret;
} else {
@@ -1155,9 +1193,24 @@ static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr *fw_hdr)
{
+ struct rtw89_fw_hdr_section_info *section_info;
+ struct rtw89_fw_hdr_section *section;
+ int i;
+
le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
FW_HDR_W7_PART_SIZE);
+ for (i = 0; i < info->section_num; i++) {
+ section_info = &info->section_info[i];
+
+ if (!section_info->len_override)
+ continue;
+
+ section = &fw_hdr->sections[i];
+ le32p_replace_bits(&section->w1, section_info->len_override,
+ FWSECTION_HDR_W1_SEC_SIZE);
+ }
+
return 0;
}
@@ -1286,10 +1339,20 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
if (info->ignore)
return 0;
+ if (info->len_override) {
+ if (info->len_override > info->len)
+ rtw89_warn(rtwdev, "override length %u larger than original %u\n",
+ info->len_override, info->len);
+ else
+ residue_len = info->len_override;
+ }
+
if (info->key_addr && info->key_len) {
- if (info->len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
- rtw89_warn(rtwdev, "ignore to copy key data because of len %d, %d, %d\n",
- info->len, FWDL_SECTION_PER_PKT_LEN, info->key_len);
+ if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
+ rtw89_warn(rtwdev,
+ "ignore to copy key data because of len %d, %d, %d, %d\n",
+ info->len, FWDL_SECTION_PER_PKT_LEN,
+ info->key_len, residue_len);
else
copy_key = true;
}
@@ -1425,6 +1488,8 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
return ret;
}
+ rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode);
+
if (rtwdev->chip->chip_id == RTL8922A &&
(fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN))
rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000);
@@ -2508,7 +2573,7 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_PS,
- H2C_FUNC_MAC_LPS_PARM, 0, 1,
+ H2C_FUNC_MAC_LPS_PARM, 0, !lps_param->psmode,
H2C_LPS_PARM_LEN);
ret = rtw89_h2c_tx(rtwdev, skb, false);
@@ -3795,6 +3860,52 @@ fail:
return ret;
}
+int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv)
+{
+ struct rtw89_h2c_tx_duty *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ u16 pause, active;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_tx_duty *)skb->data;
+
+ static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100);
+
+ if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) {
+ h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP);
+ } else {
+ active = 100 - lv * RTW89_THERMAL_PROT_STEP;
+ pause = 100 - active;
+
+ h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) |
+ le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK);
+ }
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
+ H2C_FUNC_TX_DUTY, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool connect)
@@ -4965,7 +5076,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
scan_mode = RTW89_SCAN_IMMEDIATE;
} else {
scan_mode = RTW89_SCAN_DELAY;
- tsf += option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
+ tsf += (u64)option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
}
}
@@ -5260,7 +5371,7 @@ fail:
int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_fw_h2c_rf_get_mccch *mccch;
struct sk_buff *skb;
int ret;
@@ -5307,7 +5418,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0;
struct rtw89_fw_h2c_rfk_pre_info *h2c;
- u8 tbl_sel = rfk_mcc->table_idx;
+ u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH];
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 ver = U8_MAX;
@@ -5331,19 +5442,24 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
h2c->common.mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
+ BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH);
for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) {
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
h2c->common.dbcc.ch[path][tbl] =
- cpu_to_le32(rfk_mcc->ch[tbl]);
+ cpu_to_le32(rfk_mcc->data[path].ch[tbl]);
h2c->common.dbcc.band[path][tbl] =
- cpu_to_le32(rfk_mcc->band[tbl]);
+ cpu_to_le32(rfk_mcc->data[path].band[tbl]);
}
}
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
- h2c->common.tbl.cur_ch[path] = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
- h2c->common.tbl.cur_band[path] = cpu_to_le32(rfk_mcc->band[tbl_sel]);
+ tbl_sel[path] = rfk_mcc->data[path].table_idx;
+
+ h2c->common.tbl.cur_ch[path] =
+ cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]);
+ h2c->common.tbl.cur_band[path] =
+ cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]);
}
h2c->common.phy_idx = cpu_to_le32(phy_idx);
@@ -5351,9 +5467,9 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */
h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data;
- h2c_v0->cur_band = cpu_to_le32(rfk_mcc->band[tbl_sel]);
- h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->bw[tbl_sel]);
- h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
+ h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]);
+ h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]);
+ h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]);
val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1);
h2c_v0->ktbl_sel0 = cpu_to_le32(val32);
@@ -6252,8 +6368,10 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
ch_info->period = max_t(u8, ch_info->period,
RTW89_DFS_CHAN_TIME);
ch_info->dwell_time = RTW89_DWELL_TIME;
+ ch_info->pause_data = true;
break;
case RTW89_CHAN_ACTIVE:
+ ch_info->pause_data = true;
break;
default:
rtw89_err(rtwdev, "Channel type out of bound\n");
@@ -6352,8 +6470,10 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
ch_info->period =
max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
ch_info->dwell_time = RTW89_DWELL_TIME;
+ ch_info->pause_data = true;
break;
case RTW89_CHAN_ACTIVE:
+ ch_info->pause_data = true;
break;
default:
rtw89_warn(rtwdev, "Channel type out of bound\n");
@@ -6675,6 +6795,8 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
if (!rtwvif_link)
return;
+ rtw89_chanctx_proceed(rtwdev);
+
rtwvif = rtwvif_link->rtwvif;
reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
@@ -6692,8 +6814,6 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
scan_info->last_chan_idx = 0;
scan_info->scanning_vif = NULL;
scan_info->abort = false;
-
- rtw89_chanctx_proceed(rtwdev);
}
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index d338c3aec725..efa63d444821 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -261,6 +261,7 @@ struct rtw89_fw_hdr_section_info {
u8 redl;
const u8 *addr;
u32 len;
+ u32 len_override;
u32 dladdr;
u32 mssc;
u8 type;
@@ -275,6 +276,7 @@ struct rtw89_fw_bin_info {
u32 hdr_len;
bool dynamic_hdr_en;
u32 dynamic_hdr_len;
+ u8 idmem_share_mode;
bool dsp_checksum;
bool secure_section_exist;
struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM];
@@ -563,6 +565,7 @@ struct rtw89_fw_hdr {
#define FW_HDR_W6_SEC_NUM GENMASK(15, 8)
#define FW_HDR_W7_PART_SIZE GENMASK(15, 0)
#define FW_HDR_W7_DYN_HDR BIT(16)
+#define FW_HDR_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24)
struct rtw89_fw_hdr_section_v1 {
@@ -580,6 +583,7 @@ struct rtw89_fw_hdr_section_v1 {
#define FWSECTION_HDR_V1_W1_REDL BIT(29)
#define FWSECTION_HDR_V1_W2_MSSC GENMASK(7, 0)
#define FORMATTED_MSSC 0xFF
+#define FORMATTED_MSSC_MASK GENMASK(7, 0)
#define FWSECTION_HDR_V1_W2_BBMCU_IDX GENMASK(27, 24)
struct rtw89_fw_hdr_v1 {
@@ -615,6 +619,7 @@ struct rtw89_fw_hdr_v1 {
#define FW_HDR_V1_W6_DSP_CHKSUM BIT(24)
#define FW_HDR_V1_W7_PART_SIZE GENMASK(15, 0)
#define FW_HDR_V1_W7_DYN_HDR BIT(16)
+#define FW_HDR_V1_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
enum rtw89_fw_mss_pool_rmp_tbl_type {
MSS_POOL_RMP_TBL_BITMASK = 0x0,
@@ -3689,6 +3694,13 @@ struct rtw89_c2h_pkt_ofld_rsp {
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8)
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16)
+struct rtw89_c2h_tx_duty_rpt {
+ struct rtw89_c2h_hdr c2h_hdr;
+ __le32 w2;
+} __packed;
+
+#define RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR GENMASK(2, 0)
+
struct rtw89_c2h_wow_aoac_report {
struct rtw89_c2h_hdr c2h_hdr;
u8 rpt_ver;
@@ -3713,6 +3725,15 @@ struct rtw89_c2h_wow_aoac_report {
#define RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX BIT(0)
+struct rtw89_h2c_tx_duty {
+ __le32 w0;
+ __le32 w1;
+} __packed;
+
+#define RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK GENMASK(15, 0)
+#define RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK GENMASK(31, 16)
+#define RTW89_H2C_TX_DUTY_W1_STOP BIT(0)
+
struct rtw89_h2c_bcnfltr {
__le32 w0;
} __packed;
@@ -4071,6 +4092,7 @@ enum rtw89_fw_ofld_h2c_func {
H2C_FUNC_OFLD_CFG = 0x14,
H2C_FUNC_ADD_SCANOFLD_CH = 0x16,
H2C_FUNC_SCANOFLD = 0x17,
+ H2C_FUNC_TX_DUTY = 0x18,
H2C_FUNC_PKT_DROP = 0x1b,
H2C_FUNC_CFG_BCNFLTR = 0x1e,
H2C_FUNC_OFLD_RSSI = 0x1f,
@@ -4506,6 +4528,7 @@ int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val);
int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev);
+int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv);
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool connect);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index e09f926bb4a0..7907b84d204b 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -1444,6 +1444,7 @@ void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
{
#define PWR_ACT 1
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_pwr_cfg * const *cfg_seq;
int (*cfg_func)(struct rtw89_dev *rtwdev);
@@ -1472,6 +1473,9 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
return ret;
if (on) {
+ if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
+ mac->efuse_read_fw_secure(rtwdev);
+
set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
@@ -3996,9 +4000,10 @@ fail:
static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 i;
- if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
for (i = 0; i < 4; i++) {
@@ -4010,7 +4015,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
- if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
@@ -5029,6 +5036,18 @@ rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h,
}
static void
+rtw89_mac_c2h_tx_duty_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
+{
+ struct rtw89_c2h_tx_duty_rpt *c2h =
+ (struct rtw89_c2h_tx_duty_rpt *)skb_c2h->data;
+ u8 err;
+
+ err = le32_get_bits(c2h->w2, RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "C2H TX duty rpt with err=%d\n", err);
+}
+
+static void
rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
@@ -5354,6 +5373,7 @@ void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
[RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL,
[RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause,
[RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp,
+ [RTW89_MAC_C2H_FUNC_TX_DUTY_RPT] = rtw89_mac_c2h_tx_duty_rpt,
[RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt,
[RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt,
};
@@ -6604,6 +6624,20 @@ int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev,
rtwdev, R_AX_WCPU_FW_CTRL);
}
+static
+void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+
+ if (!sec->secure_boot)
+ return;
+
+ rtw89_write32_mask(rtwdev, R_AX_WCPU_FW_CTRL,
+ B_AX_IDMEM_SHARE_MODE_RECORD_MASK, mode);
+ rtw89_write32_set(rtwdev, R_AX_WCPU_FW_CTRL,
+ B_AX_IDMEM_SHARE_MODE_RECORD_VALID);
+}
+
const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
@@ -6657,9 +6691,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax,
.fwdl_get_status = rtw89_fw_get_rdy_ax,
.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_ax,
+ .fwdl_secure_idmem_share_mode = rtw89_fwdl_secure_idmem_share_mode_ax,
.parse_efuse_map = rtw89_parse_efuse_map_ax,
.parse_phycap_map = rtw89_parse_phycap_map_ax,
.cnv_efuse_state = rtw89_cnv_efuse_state_ax,
+ .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_ax,
.cfg_plt = rtw89_mac_cfg_plt_ax,
.get_plt_cnt = rtw89_mac_get_plt_cnt_ax,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index e59c1fcfea46..18579c020548 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -391,6 +391,7 @@ enum rtw89_mac_c2h_ofld_func {
RTW89_MAC_C2H_FUNC_MACID_PAUSE,
RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT = 0x6,
RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9,
+ RTW89_MAC_C2H_FUNC_TX_DUTY_RPT = 0xa,
RTW89_MAC_C2H_FUNC_BCNFLTR_RPT = 0xd,
RTW89_MAC_C2H_FUNC_OFLD_MAX,
};
@@ -984,9 +985,11 @@ struct rtw89_mac_gen_def {
bool dlfw, bool include_bb);
u8 (*fwdl_get_status)(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type);
int (*fwdl_check_path_ready)(struct rtw89_dev *rtwdev, bool h2c_or_fwdl);
+ void (*fwdl_secure_idmem_share_mode)(struct rtw89_dev *rtwdev, u8 mode);
int (*parse_efuse_map)(struct rtw89_dev *rtwdev);
int (*parse_phycap_map)(struct rtw89_dev *rtwdev);
int (*cnv_efuse_state)(struct rtw89_dev *rtwdev, bool idle);
+ int (*efuse_read_fw_secure)(struct rtw89_dev *rtwdev);
int (*cfg_plt)(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt);
u16 (*get_plt_cnt)(struct rtw89_dev *rtwdev, u8 band);
@@ -1493,4 +1496,14 @@ int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
struct rtw89_mac_dle_rsvd_qt_cfg *cfg);
int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable);
+static inline
+void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ if (!mac->fwdl_secure_idmem_share_mode)
+ return;
+
+ return mac->fwdl_secure_idmem_share_mode(rtwdev, mode);
+}
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 3f33c3a2ae7d..619d2d3771d5 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -192,6 +192,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
if (!rtw89_rtwvif_in_list(rtwdev, rtwvif))
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
+ INIT_LIST_HEAD(&rtwvif->mgnt_entry);
+
ether_addr_copy(rtwvif->mac_addr, vif->addr);
rtwvif->offchan = false;
@@ -1375,6 +1377,7 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
+ mutex_unlock(&rtwdev->mutex);
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 30943462640f..f7a396c8a3cd 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -2600,9 +2600,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be,
.fwdl_get_status = fwdl_get_status_be,
.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be,
+ .fwdl_secure_idmem_share_mode = NULL,
.parse_efuse_map = rtw89_parse_efuse_map_be,
.parse_phycap_map = rtw89_parse_phycap_map_be,
.cnv_efuse_state = rtw89_cnv_efuse_state_be,
+ .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_be,
.cfg_plt = rtw89_mac_cfg_plt_be,
.get_plt_cnt = rtw89_mac_get_plt_cnt_be,
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 5ed7eaa18c85..b0477ece7012 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -2671,9 +2671,10 @@ static void rtw89_pci_clr_idx_all_ax(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
- u32 ret, check, dma_busy;
u32 dma_busy1 = info->dma_busy1.addr;
u32 dma_busy2 = info->dma_busy2_reg;
+ u32 check, dma_busy;
+ int ret;
check = info->dma_busy1.mask;
@@ -2698,8 +2699,9 @@ static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_rxdma_ch_idle_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
- u32 ret, check, dma_busy;
u32 dma_busy3 = info->dma_busy3_reg;
+ u32 check, dma_busy;
+ int ret;
check = B_AX_RXQ_BUSY | B_AX_RPQ_BUSY;
@@ -4175,6 +4177,36 @@ static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget)
return work_done;
}
+static
+void rtw89_check_pci_ssid_quirks(struct rtw89_dev *rtwdev,
+ struct pci_dev *pdev,
+ const struct rtw89_pci_ssid_quirk *ssid_quirks)
+{
+ int i;
+
+ if (!ssid_quirks)
+ return;
+
+ for (i = 0; i < 200; i++, ssid_quirks++) {
+ if (ssid_quirks->vendor == 0 && ssid_quirks->device == 0)
+ break;
+
+ if (ssid_quirks->vendor != pdev->vendor ||
+ ssid_quirks->device != pdev->device ||
+ ssid_quirks->subsystem_vendor != pdev->subsystem_vendor ||
+ ssid_quirks->subsystem_device != pdev->subsystem_device)
+ continue;
+
+ bitmap_or(rtwdev->quirks, rtwdev->quirks, &ssid_quirks->bitmap,
+ NUM_OF_RTW89_QUIRKS);
+ rtwdev->custid = ssid_quirks->custid;
+ break;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_HCI, "quirks=%*ph custid=%d\n",
+ (int)sizeof(rtwdev->quirks), rtwdev->quirks, rtwdev->custid);
+}
+
static int __maybe_unused rtw89_pci_suspend(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -4349,6 +4381,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rtwdev->hci.cpwm_addr = pci_info->cpwm_addr;
rtw89_check_quirks(rtwdev, info->quirks);
+ rtw89_check_pci_ssid_quirks(rtwdev, pdev, pci_info->ssid_quirks);
SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev);
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
index 796f6cd3c965..b68e2d82eea9 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.h
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
@@ -1292,6 +1292,19 @@ struct rtw89_pci_gen_def {
void (*disable_eq)(struct rtw89_dev *rtwdev);
};
+#define RTW89_PCI_SSID(v, d, ssv, ssd, cust) \
+ .vendor = v, .device = d, .subsystem_vendor = ssv, .subsystem_device = ssd, \
+ .custid = RTW89_CUSTID_ ##cust
+
+struct rtw89_pci_ssid_quirk {
+ unsigned short vendor;
+ unsigned short device;
+ unsigned short subsystem_vendor;
+ unsigned short subsystem_device;
+ enum rtw89_custid custid;
+ unsigned long bitmap; /* bitmap of rtw89_quirks */
+};
+
struct rtw89_pci_info {
const struct rtw89_pci_gen_def *gen_def;
enum mac_ax_bd_trunc_mode txbd_trunc_mode;
@@ -1345,6 +1358,8 @@ struct rtw89_pci_info {
void (*recognize_intrs)(struct rtw89_dev *rtwdev,
struct rtw89_pci *rtwpci,
struct rtw89_pci_isrs *isrs);
+
+ const struct rtw89_pci_ssid_quirk *ssid_quirks;
};
struct rtw89_pci_tx_data {
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 5a08e3d46bac..f24aca663cf0 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -4836,11 +4836,36 @@ static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev)
rtw89_phy_antdiv_reg_init(rtwdev);
}
+static void rtw89_phy_thermal_protect(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_phy_stat *phystat = &rtwdev->phystat;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u8 th_max = phystat->last_thermal_max;
+ u8 lv = hal->thermal_prot_lv;
+
+ if (!hal->thermal_prot_th ||
+ (hal->disabled_dm_bitmap & BIT(RTW89_DM_THERMAL_PROTECT)))
+ return;
+
+ if (th_max > hal->thermal_prot_th && lv < RTW89_THERMAL_PROT_LV_MAX)
+ lv++;
+ else if (th_max < hal->thermal_prot_th - 2 && lv > 0)
+ lv--;
+ else
+ return;
+
+ hal->thermal_prot_lv = lv;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection lv=%d\n", lv);
+
+ rtw89_fw_h2c_tx_duty(rtwdev, hal->thermal_prot_lv);
+}
+
static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
{
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
+ u8 th, th_max = 0;
int i;
- u8 th;
for (i = 0; i < rtwdev->chip->rf_path_num; i++) {
th = rtw89_chip_get_thermal(rtwdev, i);
@@ -4850,7 +4875,11 @@ static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
"path(%d) thermal cur=%u avg=%ld", i, th,
ewma_thermal_read(&phystat->avg_thermal[i]));
+
+ th_max = max(th_max, th);
}
+
+ phystat->last_thermal_max = th_max;
}
struct rtw89_phy_iter_rssi_data {
@@ -4923,6 +4952,8 @@ static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev)
memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat));
ewma_rssi_init(&phystat->bcn_rssi);
+
+ rtwdev->hal.thermal_prot_lv = 0;
}
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
@@ -4930,6 +4961,7 @@ void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
rtw89_phy_stat_thermal_update(rtwdev);
+ rtw89_phy_thermal_protect(rtwdev);
rtw89_phy_stat_rssi_update(rtwdev);
phystat->last_pkt_stat = phystat->cur_pkt_stat;
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 69678eab2309..18ec7c0252fb 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -196,6 +196,8 @@
#define R_AX_HALT_C2H 0x016C
#define R_AX_WCPU_FW_CTRL 0x01E0
+#define B_AX_IDMEM_SHARE_MODE_RECORD_MASK GENMASK(27, 24)
+#define B_AX_IDMEM_SHARE_MODE_RECORD_VALID BIT(23)
#define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5)
#define B_AX_FWDL_PATH_RDY BIT(2)
#define B_AX_H2C_PATH_RDY BIT(1)
diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c
index bb064a086970..cad5189708e7 100644
--- a/drivers/net/wireless/realtek/rtw89/regd.c
+++ b/drivers/net/wireless/realtek/rtw89/regd.c
@@ -646,22 +646,44 @@ static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
}
-static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
- struct wiphy *wiphy)
+static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *regd = regulatory->regd;
- struct ieee80211_supported_band *sband;
u8 index;
- int i;
index = rtw89_regd_get_index(regd);
if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
!test_bit(index, regulatory->block_6ghz))
- return;
+ return false;
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n",
regd->alpha2[0], regd->alpha2[1]);
+ return true;
+}
+
+static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd *regd = regulatory->regd;
+
+ if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA)
+ return false;
+
+ rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n",
+ regd->alpha2[0], regd->alpha2[1]);
+ return true;
+}
+
+static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
+ struct wiphy *wiphy)
+{
+ struct ieee80211_supported_band *sband;
+ int i;
+
+ if (!regd_is_6ghz_blocked(rtwdev) &&
+ !regd_is_6ghz_not_applicable(rtwdev))
+ return;
sband = wiphy->bands[NL80211_BAND_6GHZ];
if (!sband)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index f9766bf30e71..68c67a763f4d 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -282,7 +282,7 @@ static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u8 val8;
- u32 ret;
+ int ret;
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
B_AX_AFSM_PCIE_SUS_EN);
@@ -401,7 +401,7 @@ static void rtw8851b_patch_swr_pfm2pwm(struct rtw89_dev *rtwdev)
static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@@ -2454,6 +2454,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8851b_phy_bb_table,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851be.c b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
index d334924faec8..651cbce1dd7e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851be.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
@@ -60,6 +60,8 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8851be_info = {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 42d369d2e916..e647759ebd69 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2170,6 +2170,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xc000, 0xd000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = pwr_on_seq_8852a,
.pwr_off_seq = pwr_off_seq_8852a,
.bb_table = &rtw89_8852a_phy_bb_table,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
index 9a675e2193bc..701187d69e14 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
@@ -58,6 +58,8 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852ae_info = {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 364aa21cbd44..49a319128316 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -254,7 +254,7 @@ static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev)
static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
rtw8852b_pwr_sps_ana(rtwdev);
@@ -383,7 +383,7 @@ func_en:
static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
rtw8852b_pwr_sps_ana(rtwdev);
@@ -808,6 +808,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8852b_phy_bb_table,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
index ede0ca5426ae..f4aa4437fb75 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
@@ -905,7 +905,6 @@ static void rtw8852bx_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 rx_path_0;
- u32 val;
rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, phy_idx);
@@ -985,12 +984,11 @@ static void rtw8852bx_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH,
pri_ch, phy_idx);
- /*Set RF mode at A */
- val = chip_id == RTL8852BT ? 0x333 : 0xaaa;
+ /*Set RF mode at 3 */
rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, val, phy_idx);
+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, val, phy_idx);
+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
break;
default:
rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
index d8f9d92ca0fb..a13ea1cce4a7 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
@@ -60,6 +60,8 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852be_info = {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
index dab7e71ec6a1..876725133228 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
@@ -244,7 +244,7 @@ static const u8 rtw89_btc_8852bt_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30,
static int rtw8852bt_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
@@ -357,7 +357,7 @@ func_en:
static int rtw8852bt_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@@ -742,6 +742,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = NULL,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bte.c b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
index 702948119646..e4f40c2e287d 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
@@ -60,6 +60,8 @@ static const struct rtw89_pci_info rtw8852bt_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852bte_info = {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index dbe77abb2c48..cde34f8e1e67 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -203,7 +203,7 @@ static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
@@ -324,7 +324,7 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@@ -2947,6 +2947,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8852c_phy_bb_table,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
index 3281ee9d7523..bd17c0a1c684 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
@@ -1065,7 +1065,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev,
static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx = rfk_mcc->table_idx;
bool is_fail1, is_fail2;
@@ -1408,7 +1408,7 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
u8 idx = 0;
idx = rfk_mcc->table_idx;
@@ -4105,7 +4105,7 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {};
const struct rtw89_chan *chan;
enum rtw89_entity_mode mode;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
index 8aaad7d58c0d..1a46878be96b 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
@@ -67,6 +67,8 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.enable_intr = rtw89_pci_enable_intr_v1,
.disable_intr = rtw89_pci_disable_intr_v1,
.recognize_intrs = rtw89_pci_recognize_intrs_v1,
+
+ .ssid_quirks = NULL,
};
static const struct dmi_system_id rtw8852c_pci_quirks[] = {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index 58c9721ac3ab..9a4db04a1967 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2023 Realtek Corporation
*/
+#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "efuse.h"
@@ -398,9 +399,6 @@ static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
B_BE_FEN_BBPLAT_RSTB);
- if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
- rtw89_efuse_read_fw_secure_be(rtwdev);
-
return 0;
}
@@ -965,6 +963,42 @@ static const struct rtw8922a_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
.gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 },
};
+static const struct rtw8922a_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = {
+ { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x4078, 0x4478},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
+};
+
+static const struct rtw8922a_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = {
+ { .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4080, 0x4480},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4088, 0x4488},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
+ .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
+ { .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
+};
+
struct rtw8922a_bb_gain_bypass {
u32 gain_g[BB_PATH_NUM_8922A];
u32 gain_a[BB_PATH_NUM_8922A];
@@ -1056,6 +1090,30 @@ static void rtw8922a_set_lna_tia_gain(struct rtw89_dev *rtwdev,
val = gain->tia_gain[gain_band][bw_type][path][i];
rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
}
+
+ for (i = 0; i < LNA_GAIN_NUM; i++) {
+ if (chan->band_type == RTW89_BAND_2G) {
+ reg = bb_op1db_lna[i].gain_g[path];
+ mask = bb_op1db_lna[i].gain_g_mask;
+ } else {
+ reg = bb_op1db_lna[i].gain_a[path];
+ mask = bb_op1db_lna[i].gain_a_mask;
+ }
+ val = gain->lna_op1db[gain_band][bw_type][path][i];
+ rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
+ }
+
+ for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) {
+ if (chan->band_type == RTW89_BAND_2G) {
+ reg = bb_op1db_tia_lna[i].gain_g[path];
+ mask = bb_op1db_tia_lna[i].gain_g_mask;
+ } else {
+ reg = bb_op1db_tia_lna[i].gain_a[path];
+ mask = bb_op1db_tia_lna[i].gain_a_mask;
+ }
+ val = gain->tia_lna_op1db[gain_band][bw_type][path][i];
+ rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
+ }
}
static void rtw8922a_set_gain(struct rtw89_dev *rtwdev,
@@ -1745,7 +1803,7 @@ static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev,
static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+ const struct rtw89_chan *chan0, *chan1;
if (mode == MLO_1_PLUS_1_1RF || mode == DBCC_LEGACY) {
rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x1);
@@ -1758,13 +1816,20 @@ static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode
return -EOPNOTSUPP;
}
- if (mode == MLO_2_PLUS_0_1RF) {
- rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_A);
- rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_B);
+ if (mode == MLO_1_PLUS_1_1RF) {
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ } else if (mode == MLO_0_PLUS_2_1RF) {
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ chan0 = chan1;
} else {
- rtw89_warn(rtwdev, "unsupported MLO mode %d\n", mode);
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = chan0;
}
+ rtw8922a_ctrl_afe_dac(rtwdev, chan0->band_width, RF_PATH_A);
+ rtw8922a_ctrl_afe_dac(rtwdev, chan1->band_width, RF_PATH_B);
+
rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180);
if (mode == MLO_2_PLUS_0_1RF) {
@@ -2218,10 +2283,12 @@ static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
{
struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+ struct rtw89_hal *hal = &rtwdev->hal;
int th;
- /* read thermal only if debugging */
- if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK))
+ /* read thermal only if debugging or thermal protection enabled */
+ if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK) &&
+ !hal->thermal_prot_th)
return 80;
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
@@ -2652,6 +2719,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0xad, 0xb4},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = NULL,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
index 28907df7407d..c4c93f836a2f 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
@@ -252,49 +252,58 @@ static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
}
}
-static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
+static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan, u8 path)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
- enum rtw89_chanctx_idx chanctx_idx;
- const struct rtw89_chan *chan;
- enum rtw89_entity_mode mode;
- u8 s0_tbl, s1_tbl;
u8 tbl_sel;
- mode = rtw89_get_entity_mode(rtwdev);
- switch (mode) {
- case RTW89_ENTITY_MODE_MCC_PREPARE:
- chanctx_idx = RTW89_CHANCTX_1;
- break;
- default:
- chanctx_idx = RTW89_CHANCTX_0;
- break;
- }
-
- chan = rtw89_chan_get(rtwdev, chanctx_idx);
-
for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
struct rtw89_rfk_chan_desc *p = &desc[tbl_sel];
- p->ch = rfk_mcc->ch[tbl_sel];
+ p->ch = rfk_mcc->data[path].ch[tbl_sel];
p->has_band = true;
- p->band = rfk_mcc->band[tbl_sel];
+ p->band = rfk_mcc->data[path].band[tbl_sel];
p->has_bw = true;
- p->bw = rfk_mcc->bw[tbl_sel];
+ p->bw = rfk_mcc->data[path].bw[tbl_sel];
}
tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
- rfk_mcc->ch[tbl_sel] = chan->channel;
- rfk_mcc->band[tbl_sel] = chan->band_type;
- rfk_mcc->bw[tbl_sel] = chan->band_width;
- rfk_mcc->table_idx = tbl_sel;
+ rfk_mcc->data[path].ch[tbl_sel] = chan->channel;
+ rfk_mcc->data[path].band[tbl_sel] = chan->band_type;
+ rfk_mcc->data[path].bw[tbl_sel] = chan->band_width;
+ rfk_mcc->data[path].table_idx = tbl_sel;
+
+ return tbl_sel;
+}
+
+static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chan *chan0, *chan1;
+ u8 s0_tbl, s1_tbl;
+
+ switch (rtwdev->mlo_dbcc_mode) {
+ default:
+ case MLO_2_PLUS_0_1RF:
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = chan0;
+ break;
+ case MLO_0_PLUS_2_1RF:
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ chan0 = chan1;
+ break;
+ case MLO_1_PLUS_1_1RF:
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ break;
+ }
- s0_tbl = tbl_sel;
- s1_tbl = tbl_sel;
+ s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan0, 0);
+ s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan1, 1);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
index 47f855a7a268..edfb1f220af0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
@@ -9,6 +9,12 @@
#include "reg.h"
#include "rtw8922a.h"
+static const struct rtw89_pci_ssid_quirk rtw8922a_pci_ssid_quirks[] = {
+ {RTW89_PCI_SSID(PCI_VENDOR_ID_REALTEK, 0x8922, 0x10EC, 0xA891, DELL),
+ .bitmap = BIT(RTW89_QUIRK_THERMAL_PROT_120C)},
+ {},
+};
+
static const struct rtw89_pci_info rtw8922a_pci_info = {
.gen_def = &rtw89_pci_gen_be,
.txbd_trunc_mode = MAC_AX_BD_TRUNC,
@@ -58,6 +64,8 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
.enable_intr = rtw89_pci_enable_intr_v2,
.disable_intr = rtw89_pci_disable_intr_v2,
.recognize_intrs = rtw89_pci_recognize_intrs_v2,
+
+ .ssid_quirks = rtw8922a_pci_ssid_quirks,
};
static const struct rtw89_driver_info rtw89_8922ae_info = {
diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c
index 27826d909785..bcc287771b2a 100644
--- a/drivers/net/wireless/realtek/rtw89/sar.c
+++ b/drivers/net/wireless/realtek/rtw89/sar.c
@@ -27,8 +27,8 @@ static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
return RTW89_SAR_5GHZ_SUBBAND_1_2;
case 5500 ... 5720:
return RTW89_SAR_5GHZ_SUBBAND_2_E;
- case 5745 ... 5825:
- return RTW89_SAR_5GHZ_SUBBAND_3;
+ case 5745 ... 5885:
+ return RTW89_SAR_5GHZ_SUBBAND_3_4;
case 5955 ... 6155:
return RTW89_SAR_6GHZ_SUBBAND_5_L;
case 6175 ... 6415:
@@ -295,7 +295,7 @@ static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = {
{ .start_freq = 2412, .end_freq = 2484, },
{ .start_freq = 5180, .end_freq = 5320, },
{ .start_freq = 5500, .end_freq = 5720, },
- { .start_freq = 5745, .end_freq = 5825, },
+ { .start_freq = 5745, .end_freq = 5885, },
{ .start_freq = 5955, .end_freq = 6155, },
{ .start_freq = 6175, .end_freq = 6415, },
{ .start_freq = 6435, .end_freq = 6515, },