* [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU
@ 2024-08-11 20:53 Bitterblue Smith
2024-08-11 20:54 ` [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU Bitterblue Smith
` (19 more replies)
0 siblings, 20 replies; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:53 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
Patches 1..15 prepare things, patches 16..19 add the new files,
and patch 20 enables their compilation.
There are three new modules: rtw88_8821a, which handles all the logic
for both chips (like rtl8821ae in rtlwifi), rtw88_8821au, and
rtw88_8812au.
More device IDs will be added later because those are not my patches
and I assume they won't need (as m)any revisions. 20 patches is already
a lot.
Also to be added later: USB 3 support for RTL8812AU and RX aggregation
for both chips.
There are still some bugs. Sometimes all RX stops, including C2H,
but I see the chip transmitting probe requests on multiple channels.
It's pretty rare, difficult to trigger. It happened to me four times
in three months.
Bitterblue Smith (20):
wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU
wifi: rtw88: Dump the HW features only for some chips
wifi: rtw88: Allow different C2H RA report sizes
wifi: rtw88: Extend the init table parsing for RTL8812AU
wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL
wifi: rtw88: Let each driver control the power on/off process
wifi: rtw88: Enable data rate fallback for older chips
wifi: rtw88: Make txagc_remnant_ofdm an array
wifi: rtw88: Support TX page sizes bigger than 128
wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def
wifi: rtw88: usb: Set pkt_info.ls for the reserved page
wifi: rtw88: Detect beacon loss with chips other than 8822c
wifi: rtw88: coex: Support chips without a scoreboard
wifi: rtw88: 8821a: Regularly ask for BT info updates
wifi: rtw88: 8812a: Mitigate beacon loss
wifi: rtw88: Add rtw8812a_table.{c,h}
wifi: rtw88: Add rtw8821a_table.{c,h}
wifi: rtw88: Add rtw8821a.{c,h}
wifi: rtw88: Add rtw8821au.c and rtw8812au.c
wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers
drivers/net/wireless/realtek/rtw88/Kconfig | 25 +
drivers/net/wireless/realtek/rtw88/Makefile | 9 +
drivers/net/wireless/realtek/rtw88/coex.c | 37 +-
drivers/net/wireless/realtek/rtw88/coex.h | 1 +
drivers/net/wireless/realtek/rtw88/debug.c | 2 +-
drivers/net/wireless/realtek/rtw88/fw.c | 21 +-
drivers/net/wireless/realtek/rtw88/mac.c | 13 +-
drivers/net/wireless/realtek/rtw88/mac.h | 3 +
drivers/net/wireless/realtek/rtw88/main.c | 31 +-
drivers/net/wireless/realtek/rtw88/main.h | 39 +-
drivers/net/wireless/realtek/rtw88/pci.c | 2 +-
drivers/net/wireless/realtek/rtw88/phy.c | 71 +-
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 21 +-
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 21 +-
drivers/net/wireless/realtek/rtw88/rtw8723x.c | 3 +-
.../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++
.../wireless/realtek/rtw88/rtw8812a_table.h | 26 +
.../net/wireless/realtek/rtw88/rtw8812au.c | 28 +
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 4139 +++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8821a.h | 385 ++
.../wireless/realtek/rtw88/rtw8821a_table.c | 2350 ++++++++++
.../wireless/realtek/rtw88/rtw8821a_table.h | 21 +
.../net/wireless/realtek/rtw88/rtw8821au.c | 28 +
drivers/net/wireless/realtek/rtw88/rtw8821c.c | 21 +-
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 19 +-
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 27 +-
drivers/net/wireless/realtek/rtw88/sdio.c | 2 +-
drivers/net/wireless/realtek/rtw88/tx.c | 6 +-
drivers/net/wireless/realtek/rtw88/tx.h | 4 +-
drivers/net/wireless/realtek/rtw88/usb.c | 5 +-
30 files changed, 10083 insertions(+), 89 deletions(-)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c
--
2.46.0
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
@ 2024-08-11 20:54 ` Bitterblue Smith
2024-08-15 6:34 ` Ping-Ke Shih
2024-08-11 20:54 ` [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips Bitterblue Smith
` (18 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:54 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
Add 8821A and 8812A chip type enums.
Add cck_high_power member to struct rtw_hal. This will be used to
calculate the RX signal strength.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 12b564ad3a58..7e4618095eca 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 {
@@ -1936,6 +1938,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;
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
2024-08-11 20:54 ` [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU Bitterblue Smith
@ 2024-08-11 20:54 ` Bitterblue Smith
2024-08-15 6:10 ` Ping-Ke Shih
2024-08-11 20:55 ` [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes Bitterblue Smith
` (17 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:54 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
RTL8821AU and RTL8812AU don't support this. They hit the "failed to read
hw feature report" error.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 4 ++++
drivers/net/wireless/realtek/rtw88/main.h | 1 +
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
7 files changed, 10 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index ff045dfdca4a..aeb21ac25e2e 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1923,6 +1923,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
u8 bw;
int i;
+ if (!rtwdev->chip->hw_feature_report)
+ goto print_hw_cap;
+
id = rtw_read8(rtwdev, REG_C2HEVT);
if (id != C2H_HW_FEATURE_REPORT) {
rtw_err(rtwdev, "failed to read hw feature report\n");
@@ -1947,6 +1950,7 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
efuse->hw_cap.nss > rtwdev->hal.rf_path_num)
efuse->hw_cap.nss = rtwdev->hal.rf_path_num;
+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,
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 7e4618095eca..16619432f450 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1202,6 +1202,7 @@ struct rtw_chip_info {
const struct rtw_fwcd_segs *fwcd_segs;
u8 usb_tx_agg_desc_num;
+ bool hw_feature_report;
u8 default_1ss_tx_path;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index 222608de33cd..c9bb779812b6 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -2014,6 +2014,7 @@ 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,
.path_div_supported = false,
.ht_supported = true,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 3fba4054d45f..fea327e5a474 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -2172,6 +2172,7 @@ 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,
.ht_supported = true,
.vht_supported = false,
.lps_deep_mode_supported = 0,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 526e8de77b3e..a95bca79ce02 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -2009,6 +2009,7 @@ 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,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 6edb17aea90e..42f055eec16b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2550,6 +2550,7 @@ 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,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 1dbe1cdbc3fd..c646bd4ec5e2 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -5371,6 +5371,7 @@ 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,
.default_1ss_tx_path = BB_PATH_A,
.path_div_supported = true,
.ht_supported = true,
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
2024-08-11 20:54 ` [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU Bitterblue Smith
2024-08-11 20:54 ` [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips Bitterblue Smith
@ 2024-08-11 20:55 ` Bitterblue Smith
2024-08-15 6:14 ` Ping-Ke Shih
2024-08-11 20:55 ` [PATCH 04/20] wifi: rtw88: Extend the init table parsing for RTL8812AU Bitterblue Smith
` (16 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:55 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
Avoid the "invalid ra report c2h length" error.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
drivers/net/wireless/realtek/rtw88/main.h | 1 +
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
7 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 782f3776e0a0..ac53e3e30af0 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
rate = GET_RA_REPORT_RATE(ra_data->payload);
sgi = GET_RA_REPORT_SGI(ra_data->payload);
- bw = GET_RA_REPORT_BW(ra_data->payload);
+ if (si->rtwdev->chip->c2h_ra_report_size < 7)
+ bw = si->bw_mode;
+ else
+ bw = GET_RA_REPORT_BW(ra_data->payload);
if (rate < DESC_RATEMCS0) {
si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate);
@@ -199,7 +202,8 @@ static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *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);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 16619432f450..baf3098e93ba 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1203,6 +1203,7 @@ struct rtw_chip_info {
u8 usb_tx_agg_desc_num;
bool hw_feature_report;
+ u8 c2h_ra_report_size;
u8 default_1ss_tx_path;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index c9bb779812b6..8f90320e1c51 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -2015,6 +2015,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.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,
.path_div_supported = false,
.ht_supported = true,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index fea327e5a474..85f3abee32fc 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -2173,6 +2173,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.dig_min = 0x20,
.usb_tx_agg_desc_num = 1,
.hw_feature_report = true,
+ .c2h_ra_report_size = 7,
.ht_supported = true,
.vht_supported = false,
.lps_deep_mode_supported = 0,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index a95bca79ce02..76726632c048 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -2010,6 +2010,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
.dig_min = 0x1c,
.usb_tx_agg_desc_num = 3,
.hw_feature_report = true,
+ .c2h_ra_report_size = 7,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 42f055eec16b..9dde02dbbb62 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2551,6 +2551,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
.dig_min = 0x1c,
.usb_tx_agg_desc_num = 3,
.hw_feature_report = true,
+ .c2h_ra_report_size = 7,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index c646bd4ec5e2..5dabcd0efb1d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -5372,6 +5372,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
.dig_min = 0x20,
.usb_tx_agg_desc_num = 3,
.hw_feature_report = true,
+ .c2h_ra_report_size = 7,
.default_1ss_tx_path = BB_PATH_A,
.path_div_supported = true,
.ht_supported = true,
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 04/20] wifi: rtw88: Extend the init table parsing for RTL8812AU
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (2 preceding siblings ...)
2024-08-11 20:55 ` [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes Bitterblue Smith
@ 2024-08-11 20:55 ` Bitterblue Smith
2024-08-15 6:27 ` Ping-Ke Shih
2024-08-11 20:57 ` [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL Bitterblue Smith
` (15 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:55 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
The chips supported so far only use the first condition, and so the
parsing code ignores the second condition. RTL8812AU's init tables use
the second condition also. Make the parsing code check it.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.h | 15 ++++++
drivers/net/wireless/realtek/rtw88/phy.c | 57 ++++++++++++++++++++---
2 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index baf3098e93ba..c827320c1b9b 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1837,6 +1837,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;
@@ -1918,6 +1932,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;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index 37ef80c9091d..70f3cf06323b 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;
};
@@ -1042,6 +1045,7 @@ 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_cond2 cond2 = {0};
cond.cut = hal->cut_version ? hal->cut_version : 15;
cond.pkg = pkg ? pkg : 15;
@@ -1061,15 +1065,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 +1103,28 @@ 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) {
+ 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;
}
@@ -1091,6 +1134,7 @@ 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_cond2 pos_cond2 = {0};
bool is_matched = true, is_skipped = false;
BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair));
@@ -1109,11 +1153,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 {
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (3 preceding siblings ...)
2024-08-11 20:55 ` [PATCH 04/20] wifi: rtw88: Extend the init table parsing for RTL8812AU Bitterblue Smith
@ 2024-08-11 20:57 ` Bitterblue Smith
2024-08-15 6:33 ` Ping-Ke Shih
2024-08-11 20:57 ` [PATCH 06/20] wifi: rtw88: Let each driver control the power on/off process Bitterblue Smith
` (14 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:57 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
RTL8821A doesn't have this. Trying to use it results in error messages,
so don't try if ltecoex_addr is NULL.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/coex.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index de3332eb7a22..47d32a6f3345 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -950,12 +950,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);
}
@@ -3922,7 +3928,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);
@@ -3934,8 +3940,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) &&
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 06/20] wifi: rtw88: Let each driver control the power on/off process
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (4 preceding siblings ...)
2024-08-11 20:57 ` [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL Bitterblue Smith
@ 2024-08-11 20:57 ` Bitterblue Smith
2024-08-11 20:59 ` [PATCH 07/20] wifi: rtw88: Enable data rate fallback for older chips Bitterblue Smith
` (13 subsequent siblings)
19 siblings, 0 replies; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:57 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
RTL8821AU and RTL8812AU have to do some things differently, so let
them have full control.
The other chips use the same functions as before.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/coex.c | 3 +++
drivers/net/wireless/realtek/rtw88/mac.c | 11 +++++++----
drivers/net/wireless/realtek/rtw88/mac.h | 3 +++
drivers/net/wireless/realtek/rtw88/main.c | 13 ++++++++-----
drivers/net/wireless/realtek/rtw88/main.h | 5 +++++
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2 ++
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 2 ++
drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 ++
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 ++
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 ++
10 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index 47d32a6f3345..7f12dcc03d70 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -2771,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)
{
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 564f5988ee82..ed7e95d5d11c 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 **cmd_seq)
+int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
+ const struct rtw_pwr_seq_cmd **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;
@@ -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..cd86e0b779cc 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 **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 aeb21ac25e2e..3806e57400fb 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1315,7 +1315,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;
@@ -1335,6 +1335,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)
@@ -1356,7 +1357,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;
@@ -1419,6 +1420,7 @@ static int rtw_power_on(struct rtw_dev *rtwdev)
err:
return ret;
}
+EXPORT_SYMBOL(rtw_power_on);
void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
{
@@ -1491,7 +1493,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;
@@ -1511,12 +1513,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)
{
@@ -1541,7 +1544,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,
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index c827320c1b9b..49af0daa5e67 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -844,6 +844,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);
@@ -2200,6 +2202,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);
@@ -2214,6 +2217,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/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index 8f90320e1c51..c2af095af5a9 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -1942,6 +1942,8 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
};
static 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,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 85f3abee32fc..44fbf53c0c2b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -1431,6 +1431,8 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
}
static 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_rx_desc = rtw8723d_query_rx_desc,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 76726632c048..851bf018c911 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -1684,6 +1684,8 @@ static struct rtw_prioq_addrs prioq_addrs_8821c = {
};
static 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_rx_desc = rtw8821c_query_rx_desc,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 9dde02dbbb62..fea7de9d6603 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2173,6 +2173,8 @@ static struct rtw_prioq_addrs prioq_addrs_8822b = {
};
static 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_rx_desc = rtw8822b_query_rx_desc,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 5dabcd0efb1d..d9bf992493fb 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4989,6 +4989,8 @@ static struct rtw_prioq_addrs prioq_addrs_8822c = {
};
static 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_rx_desc = rtw8822c_query_rx_desc,
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 07/20] wifi: rtw88: Enable data rate fallback for older chips
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (5 preceding siblings ...)
2024-08-11 20:57 ` [PATCH 06/20] wifi: rtw88: Let each driver control the power on/off process Bitterblue Smith
@ 2024-08-11 20:59 ` Bitterblue Smith
2024-08-15 6:46 ` Ping-Ke Shih
2024-08-11 21:00 ` [PATCH 08/20] wifi: rtw88: Make txagc_remnant_ofdm an array Bitterblue Smith
` (12 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 20:59 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
RTL8811AU fails to perform the 4-way handshake when the AP is too far
because it transmits the EAPOL frames at MCS9 and when that doesn't
work it retries 48 times with the same rate, to no avail.
Retrying 48 times with the same rate seems pointless. Set the
appropriate field in the TX descriptor to allow it to use lower rates
when retrying.
Set it for RTL8723D and RTL8703B because they interpret this field the
same way as RTL8811A.
The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in
the TX descriptor differently, so leave it alone for those chips.
Tested with RTL8811AU and RTL8723DU.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/fw.c | 2 +-
drivers/net/wireless/realtek/rtw88/main.h | 1 +
drivers/net/wireless/realtek/rtw88/pci.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
drivers/net/wireless/realtek/rtw88/sdio.c | 2 +-
drivers/net/wireless/realtek/rtw88/tx.c | 6 +++++-
drivers/net/wireless/realtek/rtw88/tx.h | 4 +++-
drivers/net/wireless/realtek/rtw88/usb.c | 4 ++--
9 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index ac53e3e30af0..69ebddf69dbb 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1285,7 +1285,7 @@ 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)
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 49af0daa5e67..0cd37c3da3c3 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1206,6 +1206,7 @@ struct rtw_chip_info {
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;
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index 0b9b8807af2c..ecc2b3d29035 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/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index c2af095af5a9..ffd9857348a3 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -2018,6 +2018,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.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,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 44fbf53c0c2b..e31570c7b01c 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -2176,6 +2176,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.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,
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 21d0754dd7f6..26321a072df7 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 c02ac673be32..42f4e5141fe7 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;
@@ -66,6 +67,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 324189606257..056d3d7ded0a 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -43,6 +43,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)
@@ -93,7 +94,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 e83ab6fb83f5..05aa8ffe7d8f 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -457,7 +457,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,
@@ -524,7 +524,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;
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 08/20] wifi: rtw88: Make txagc_remnant_ofdm an array
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (6 preceding siblings ...)
2024-08-11 20:59 ` [PATCH 07/20] wifi: rtw88: Enable data rate fallback for older chips Bitterblue Smith
@ 2024-08-11 21:00 ` Bitterblue Smith
2024-08-15 6:50 ` Ping-Ke Shih
2024-08-11 21:00 ` [PATCH 09/20] wifi: rtw88: Support TX page sizes bigger than 128 Bitterblue Smith
` (11 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:00 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
txagc_remnant_ofdm member of struct rtw_dm_info should be different for
each RF path, so make it an array of size RTW_RF_PATH_MAX (4).
Until now all the chips using this had only one RF path, but RTL8812AU
has two, and RTL8814AU has four.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.h | 2 +-
drivers/net/wireless/realtek/rtw88/phy.c | 4 ++--
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 4 ++--
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 0cd37c3da3c3..e737cff2e1cc 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1717,7 +1717,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 */
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index 70f3cf06323b..a72aeafe5865 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -2170,8 +2170,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);
}
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index ffd9857348a3..52e1d3a43868 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -640,7 +640,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)
@@ -1643,7 +1643,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);
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index e31570c7b01c..f0f4423810da 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)
@@ -1306,7 +1306,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);
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 09/20] wifi: rtw88: Support TX page sizes bigger than 128
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (7 preceding siblings ...)
2024-08-11 21:00 ` [PATCH 08/20] wifi: rtw88: Make txagc_remnant_ofdm an array Bitterblue Smith
@ 2024-08-11 21:00 ` Bitterblue Smith
2024-08-15 6:52 ` Ping-Ke Shih
2024-08-11 21:01 ` [PATCH 10/20] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def Bitterblue Smith
` (10 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:00 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
All the chips supported so far have a TX page size of 128 bytes.
Change the type of the page_size member of struct rtw_chip_info from u8
to u16 in order to support RTL8821AU (page size of 256 bytes) and
RTL8812AU (page size of 512 bytes). Also change the types of several
related variables and function parameters from u8 to u16.
The TX page size is used, among other things, to construct the beacon,
null data, QOS null data, and PS poll templates which are uploaded to
the chip's reserved page. Each template needs to be aligned on a
multiple of the TX page size. Power saving can't work if the TX page
size is wrong.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/debug.c | 2 +-
drivers/net/wireless/realtek/rtw88/fw.c | 11 ++++++-----
drivers/net/wireless/realtek/rtw88/mac.c | 2 +-
drivers/net/wireless/realtek/rtw88/main.h | 2 +-
4 files changed, 9 insertions(+), 8 deletions(-)
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 69ebddf69dbb..19231082329f 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1288,13 +1288,13 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *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;
@@ -1602,7 +1602,7 @@ static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size)
struct rtw_rsvd_page *rsvd_pkt;
u32 page = 0;
u8 total_page = 0;
- u8 page_size, page_margin, tx_desc_sz;
+ u16 page_size, page_margin, tx_desc_sz;
u8 *buf;
int ret;
@@ -2008,7 +2008,8 @@ 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;
+ u8 page_offset = 1, *buf;
+ u16 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;
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index ed7e95d5d11c..c4c2501e27c4 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -1138,7 +1138,7 @@ int rtw_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
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index e737cff2e1cc..c78f9138d1bc 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1189,7 +1189,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;
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 10/20] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (8 preceding siblings ...)
2024-08-11 21:00 ` [PATCH 09/20] wifi: rtw88: Support TX page sizes bigger than 128 Bitterblue Smith
@ 2024-08-11 21:01 ` Bitterblue Smith
2024-08-15 7:00 ` Ping-Ke Shih
2024-08-11 21:02 ` [PATCH 11/20] wifi: rtw88: usb: Set pkt_info.ls for the reserved page Bitterblue Smith
` (9 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:01 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
RTL8812AU uses one set of TX power tracking tables for RFE 3, and
another set for everything else.
Move pwr_track_tbl from struct rtw_chip_info to struct rtw_rfe_def in
order to load the right set of tables for each RFE (RF front end) type.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.h | 8 ++++---
drivers/net/wireless/realtek/rtw88/phy.c | 3 ++-
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 12 +++++-----
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 12 +++++-----
drivers/net/wireless/realtek/rtw88/rtw8723x.c | 3 ++-
drivers/net/wireless/realtek/rtw88/rtw8821c.c | 17 +++++++-------
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 15 ++++++------
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 23 +++++++++----------
8 files changed, 47 insertions(+), 46 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index c78f9138d1bc..bc444c4cfade 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1102,16 +1102,19 @@ struct rtw_rfe_def {
const struct rtw_table *phy_pg_tbl;
const struct rtw_table *txpwr_lmt_tbl;
const struct rtw_table *agc_btg_tbl;
+ const struct rtw_pwr_track_tbl *pwr_track_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, \
}
@@ -1245,7 +1248,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;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index a72aeafe5865..cfe12a75ff84 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -2385,7 +2385,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/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index 52e1d3a43868..71b015580408 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -496,11 +496,6 @@ static const struct rtw_pwr_seq_cmd *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},
@@ -1872,6 +1867,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 */
@@ -2051,7 +2052,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 f0f4423810da..b602ddc69415 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -2061,11 +2061,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
@@ -2129,6 +2124,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},
@@ -2200,7 +2201,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/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 851bf018c911..bdbb16c51181 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -1622,13 +1622,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 struct rtw_hw_reg rtw8821c_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
};
@@ -1940,7 +1933,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],
@@ -1963,6 +1956,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},
@@ -2034,7 +2034,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/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index fea7de9d6603..fa508a8c785c 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2113,12 +2113,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 },
@@ -2473,7 +2467,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],
@@ -2496,6 +2490,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},
@@ -2575,7 +2575,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/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index d9bf992493fb..8cfca006f38d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4925,16 +4925,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 },
@@ -5280,7 +5270,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],
@@ -5303,6 +5293,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 struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
@@ -5401,7 +5401,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,
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 11/20] wifi: rtw88: usb: Set pkt_info.ls for the reserved page
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (9 preceding siblings ...)
2024-08-11 21:01 ` [PATCH 10/20] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def Bitterblue Smith
@ 2024-08-11 21:02 ` Bitterblue Smith
2024-08-15 7:07 ` Ping-Ke Shih
2024-08-11 21:02 ` [PATCH 12/20] wifi: rtw88: Detect beacon loss with chips other than 8822c Bitterblue Smith
` (8 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:02 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
"ls" meaning "last segment". Without this RTL8812AU can't upload the
reserved page in USB 2 mode. (Somehow it's fine in USB 3 mode.)
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index 05aa8ffe7d8f..df190a31f930 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -477,6 +477,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);
}
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 12/20] wifi: rtw88: Detect beacon loss with chips other than 8822c
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (10 preceding siblings ...)
2024-08-11 21:02 ` [PATCH 11/20] wifi: rtw88: usb: Set pkt_info.ls for the reserved page Bitterblue Smith
@ 2024-08-11 21:02 ` Bitterblue Smith
2024-08-15 7:16 ` Ping-Ke Shih
2024-08-11 21:03 ` [PATCH 13/20] wifi: rtw88: coex: Support chips without a scoreboard Bitterblue Smith
` (7 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:02 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
The driver is supposed to avoid entering LPS (power saving) when there
is beacon loss, but only RTL8822C detects the beacon loss (because it
has beacon filtering in the firmware).
Detect beacon loss with the other chips by checking if we received less
than half the expected number of beacons in the last 2-second interval.
This gets rid of the occasional "failed to get tx report from firmware"
warnings with RTL8821AU. It may also avoid some disconnections.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 3806e57400fb..62d9abc04a34 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -254,6 +254,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
goto unlock;
+ int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt;
+
/* make sure BB/RF is working for dynamic mech */
rtw_leave_lps(rtwdev);
rtw_coex_wl_status_check(rtwdev);
@@ -270,6 +272,15 @@ static void rtw_watch_dog_work(struct work_struct *work)
*/
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
+ if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) &&
+ data.rtwvif) {
+ int beacon_int = rtwvif_to_vif(data.rtwvif)->bss_conf.beacon_int;
+ int watchdog_delay = 2000000 / 1024; /* TU */
+ int expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int);
+
+ rtwdev->beacon_loss = received_beacons < expected_beacons / 2;
+ }
+
/* 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
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 13/20] wifi: rtw88: coex: Support chips without a scoreboard
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (11 preceding siblings ...)
2024-08-11 21:02 ` [PATCH 12/20] wifi: rtw88: Detect beacon loss with chips other than 8822c Bitterblue Smith
@ 2024-08-11 21:03 ` Bitterblue Smith
2024-08-15 7:19 ` Ping-Ke Shih
2024-08-11 21:04 ` [PATCH 14/20] wifi: rtw88: 8821a: Regularly ask for BT info updates Bitterblue Smith
` (6 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
All the chips currently supported have a "scoreboard": the chip keeps
track of certain things related to bluetooth, for example, whether
bluetooth is active. The information can be read from register 0xaa.
RTL8821AU doesn't have this. Implement bluetooth activity detection in
rtw_coex_monitor_bt_enable() based on the bluetooth TX/RX counters.
This is mostly important for RTL8811AU, the version of RTL8821AU without
bluetooth. Without this change, the driver thinks bluetooth is active
and the wifi speeds are low.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/coex.c | 18 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/main.h | 1 +
2 files changed, 19 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index 7f12dcc03d70..39fbc5ef82f8 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -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) {
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index bc444c4cfade..bd43bb759949 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1496,6 +1496,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;
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 14/20] wifi: rtw88: 8821a: Regularly ask for BT info updates
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (12 preceding siblings ...)
2024-08-11 21:03 ` [PATCH 13/20] wifi: rtw88: coex: Support chips without a scoreboard Bitterblue Smith
@ 2024-08-11 21:04 ` Bitterblue Smith
2024-08-15 7:26 ` Ping-Ke Shih
2024-08-11 21:05 ` [PATCH 15/20] wifi: rtw88: 8812a: Mitigate beacon loss Bitterblue Smith
` (5 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
The RTL8821AU firmware sends C2H_BT_INFO by itself when bluetooth
headphones are connected, but not when they are disconnected. This leads
to the coexistence code still using the A2DP algorithm long after the
headphones are disconnected, which means the wifi speeds are much lower
than they should be. Work around this by asking for updates every two
seconds if the chip is RTL8821AU.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/coex.c | 2 +-
drivers/net/wireless/realtek/rtw88/coex.h | 1 +
drivers/net/wireless/realtek/rtw88/main.c | 3 +++
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index 39fbc5ef82f8..91e21bdfb569 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;
diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h
index 57cf29da9ea4..b6400e87e78d 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);
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 62d9abc04a34..699870ca1a9f 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -261,6 +261,9 @@ static void rtw_watch_dog_work(struct work_struct *work)
rtw_coex_wl_status_check(rtwdev);
rtw_coex_query_bt_hid_list(rtwdev);
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex)
+ rtw_coex_query_bt_info(rtwdev);
+
rtw_phy_dynamic_mechanism(rtwdev);
rtw_hci_dynamic_rx_agg(rtwdev,
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 15/20] wifi: rtw88: 8812a: Mitigate beacon loss
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (13 preceding siblings ...)
2024-08-11 21:04 ` [PATCH 14/20] wifi: rtw88: 8821a: Regularly ask for BT info updates Bitterblue Smith
@ 2024-08-11 21:05 ` Bitterblue Smith
2024-08-15 7:31 ` Ping-Ke Shih
2024-08-11 21:06 ` [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h} Bitterblue Smith
` (4 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:05 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
The RTL8812AU has a reception problem, maybe only in the 5 GHz band.
Sometimes, in some positions, it stops receiving anything even though
the distance to the AP is only ~3 meters and there are no obstacles.
Moving it a few centimeters fixes it.
Switch the initial gain to maximum coverage when there is beacon loss.
This only helps sometimes. This is similar to what the official driver
does.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/phy.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index cfe12a75ff84..fdca4e3c1038 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -530,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);
}
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h}
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (14 preceding siblings ...)
2024-08-11 21:05 ` [PATCH 15/20] wifi: rtw88: 8812a: Mitigate beacon loss Bitterblue Smith
@ 2024-08-11 21:06 ` Bitterblue Smith
2024-08-15 7:53 ` Ping-Ke Shih
2024-08-16 1:19 ` Ping-Ke Shih
2024-08-11 21:06 ` [PATCH 17/20] wifi: rtw88: Add rtw8821a_table.{c,h} Bitterblue Smith
` (3 subsequent siblings)
19 siblings, 2 replies; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:06 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
These contain various arrays for initialising RTL8812AU. Also TX power
limits.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
.../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++++++++
.../wireless/realtek/rtw88/rtw8812a_table.h | 26 +
2 files changed, 2838 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h
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..0d005d88b0a4
--- /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) 2018-2019 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 *card_enable_flow_8812a[] = {
+ trans_carddis_to_cardemu_8812a,
+ trans_cardemu_to_act_8812a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[] = {
+ trans_act_to_lps_8812a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd *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..15ecc72b175a
--- /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) 2018-2019 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 *card_enable_flow_8812a[];
+extern const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[];
+extern const struct rtw_pwr_seq_cmd *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
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 17/20] wifi: rtw88: Add rtw8821a_table.{c,h}
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (15 preceding siblings ...)
2024-08-11 21:06 ` [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h} Bitterblue Smith
@ 2024-08-11 21:06 ` Bitterblue Smith
2024-08-15 7:55 ` Ping-Ke Shih
2024-08-11 21:07 ` [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h} Bitterblue Smith
` (2 subsequent siblings)
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:06 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
These contain various arrays for initialising RTL8821AU. Also TX power
limits.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
.../wireless/realtek/rtw88/rtw8821a_table.c | 2350 +++++++++++++++++
.../wireless/realtek/rtw88/rtw8821a_table.h | 21 +
2 files changed, 2371 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h
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..32ddd460e7bb
--- /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) 2018-2019 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 *card_enable_flow_8821a[] = {
+ trans_carddis_to_cardemu_8821a,
+ trans_cardemu_to_act_8821a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd *enter_lps_flow_8821a[] = {
+ trans_act_to_lps_8821a,
+ NULL
+};
+
+const struct rtw_pwr_seq_cmd *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..070ffdbcd271
--- /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) 2018-2019 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 *card_enable_flow_8821a[];
+extern const struct rtw_pwr_seq_cmd *enter_lps_flow_8821a[];
+extern const struct rtw_pwr_seq_cmd *card_disable_flow_8821a[];
+
+extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl;
+
+#endif
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (16 preceding siblings ...)
2024-08-11 21:06 ` [PATCH 17/20] wifi: rtw88: Add rtw8821a_table.{c,h} Bitterblue Smith
@ 2024-08-11 21:07 ` Bitterblue Smith
2024-08-16 6:06 ` Ping-Ke Shih
2024-08-11 21:08 ` [PATCH 19/20] wifi: rtw88: Add rtw8821au.c and rtw8812au.c Bitterblue Smith
2024-08-11 21:11 ` [PATCH 20/20] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers Bitterblue Smith
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:07 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
These contain all the logic for the RTL8821AU and RTL8812AU chips.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 4139 +++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8821a.h | 385 ++
2 files changed, 4524 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
new file mode 100644
index 000000000000..e72599db74ed
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
@@ -0,0 +1,4139 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#include <linux/usb.h>
+#include "main.h"
+#include "coex.h"
+#include "fw.h"
+#include "tx.h"
+#include "rx.h"
+#include "phy.h"
+#include "rtw8821a.h"
+#include "rtw8821a_table.h"
+#include "rtw8812a_table.h"
+#include "mac.h"
+#include "reg.h"
+#include "sec.h"
+#include "debug.h"
+#include "bf.h"
+#include "regd.h"
+#include "efuse.h"
+#include "usb.h"
+
+static void rtw8821a_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);
+ }
+}
+
+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 rtw8821a_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 rtw8812a_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)
+ return;
+
+ 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);
+ }
+ }
+}
+
+static int rtw8821a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw8821a_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 rtw8821a_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;
+
+ rtw8812a_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;
+}
+
+static void rtw8821a_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 rtw8812au_hw_reset(struct rtw_dev *rtwdev)
+{
+ u8 val8;
+
+ if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL))
+ return;
+
+ rtw8821a_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 rtw8812au_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 = HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
+ PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_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 rtw8821a_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 rtw8821a_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 = rtw8821a_llt_write(rtwdev, i, i + 1);
+ if (status)
+ return status;
+ }
+
+ status = rtw8821a_llt_write(rtwdev, boundary - 1, 0xFF);
+ if (status)
+ return status;
+
+ for (i = boundary; i < last_entry; i++) {
+ status = rtw8821a_llt_write(rtwdev, i, i + 1);
+ if (status)
+ return status;
+ }
+
+ status = rtw8821a_llt_write(rtwdev, last_entry, boundary);
+
+ return status;
+}
+
+static void rtw8821au_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 rtw8821au_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 rtw8821au_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 rtw8821a_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 rtw8821a_init_adaptive_ctrl(struct rtw_dev *rtwdev)
+{
+ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1);
+ rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030);
+}
+
+static void rtw8821a_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 rtw8821au_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 rtw8821a_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 rtw8821a_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 rtw8821a_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, 0x8bc, 0xc0000060, 0x4);
+
+ /* RF Path_B HSSI OFF */
+ rtw_write32_mask(rtwdev, 0xe00, 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 rtw8821a_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 rtw8821a_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 rtw8821a_get_swing_index(struct rtw_dev *rtwdev)
+{
+ u32 swing, table_value;
+ u8 i = 0;
+
+ swing = rtw8821a_get_bb_swing(rtwdev, rtwdev->hal.current_band_type,
+ RF_PATH_A);
+
+ for (i = 0; i < ARRAY_SIZE(rtw8821a_txscale_tbl); i++) {
+ table_value = rtw8821a_txscale_tbl[i];
+ if (swing == table_value)
+ break;
+ }
+
+ return i;
+}
+
+static void rtw8821a_pwrtrack_init(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 ofdm_swing_idx;
+ u8 path;
+
+ ofdm_swing_idx = rtw8821a_get_swing_index(rtwdev);
+
+ if (ofdm_swing_idx >= ARRAY_SIZE(rtw8821a_txscale_tbl))
+ dm_info->default_ofdm_index = 24;
+ else
+ dm_info->default_ofdm_index = ofdm_swing_idx;
+
+ 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;
+}
+
+static void rtw8821a_power_off(struct rtw_dev *rtwdev)
+{
+ 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, 0xf008, 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);
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
+ rtw_pwr_seq_parser(rtwdev, enter_lps_flow_8821a);
+ else
+ rtw_pwr_seq_parser(rtwdev, enter_lps_flow_8812a);
+
+ if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)
+ rtw8821a_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);
+}
+
+static void rtw8821a_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band)
+{
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK,
+ rtw8821a_get_bb_swing(rtwdev, band, RF_PATH_A));
+ rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK,
+ rtw8821a_get_bb_swing(rtwdev, band, RF_PATH_B));
+ rtw8821a_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 rtw8821a_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);
+ }
+
+ rtw8821a_set_channel_bb_swing(rtwdev, new_band);
+}
+
+static int rtw8821a_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.
+ */
+ rtw8812au_hw_reset(rtwdev);
+
+ ret = rtw8812au_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 = rtw8821a_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);
+
+ rtw8821au_init_queue_reserved_page(rtwdev);
+ rtw8821au_init_tx_buffer_boundary(rtwdev);
+ rtw8821au_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);
+
+ rtw8821a_init_wmac_setting(rtwdev);
+ rtw8821a_init_adaptive_ctrl(rtwdev);
+ rtw8821a_init_edca(rtwdev);
+
+ rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7));
+ rtw_write8(rtwdev, REG_ACKTO, 0x80);
+
+ rtw8821au_tx_aggregation(rtwdev);
+
+ rtw8821a_init_beacon_parameters(rtwdev);
+ rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff);
+
+ rtw_hci_interface_cfg(rtwdev);
+
+ /* usb3 rx interval */
+ rtw_write8(rtwdev, 0xf050, 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, 0xf008, 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, MACTXEN | MACRXEN);
+
+ rtw8821a_phy_bb_config(rtwdev);
+ rtw8821a_phy_rf_config(rtwdev);
+
+ if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1)
+ rtw8812a_config_1t(rtwdev);
+
+ rtw8821a_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);
+
+ rtw8821a_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:
+ rtw8821a_power_off(rtwdev);
+
+err:
+ return ret;
+}
+
+static u32 rtw8821a_phy_read_rf(struct rtw_dev *rtwdev,
+ enum rtw_rf_path rf_path, u32 addr, u32 mask)
+{
+ static const u32 pi_addr[2] = { 0xc00, 0xe00 };
+ 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;
+}
+
+static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
+{
+ /* Nothing to do. */
+}
+
+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 rtw8821a_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, 0x18,
+ 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, 0x18, RF18_CHANNEL_MASK, channel);
+ }
+}
+
+static void rtw8821a_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 rtw8821a_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;
+
+ rtw8821a_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 rtw8821a_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, 0x18, RF18_BW_MASK, 3);
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rtw_write_rf(rtwdev, path, 0x18, RF18_BW_MASK, 1);
+ break;
+ case RTW_CHANNEL_WIDTH_80:
+ rtw_write_rf(rtwdev, path, 0x18, RF18_BW_MASK, 0);
+ break;
+ }
+ }
+}
+
+static void rtw8821a_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)
+ rtw8821a_switch_band(rtwdev, new_band, bw);
+
+ rtw8821a_switch_channel(rtwdev, channel, bw);
+
+ rtw8821a_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);
+
+ rtw8821a_set_channel_rf(rtwdev, channel, bw);
+}
+
+static s8 rtw8821a_cck_rx_pwr(struct rtw_dev *rtwdev, 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 s8 rtw8812a_cck_rx_pwr(struct rtw_dev *rtwdev, 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 rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw8821a_phy_status_rpt *phy_sts;
+ u8 lna_idx, vga_idx, cck_agc_rpt;
+ s8 rx_pwr_db, power_a, power_b;
+ const s8 min_rx_power = -120;
+ u8 rssi, val, i;
+
+ phy_sts = (struct rtw8821a_phy_status_rpt *)phy_status;
+
+ if (pkt_stat->rate <= DESC_RATE11M) {
+ cck_agc_rpt = phy_sts->cfosho[0];
+ lna_idx = (cck_agc_rpt & 0xE0) >> 5;
+ vga_idx = cck_agc_rpt & 0x1F;
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
+ rx_pwr_db = rtw8821a_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
+ else
+ rx_pwr_db = rtw8812a_cck_rx_pwr(rtwdev, 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;
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A &&
+ !rtwdev->hal.cck_high_power) {
+ 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;
+ }
+ } else { /* OFDM rate */
+ for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) {
+ val = phy_sts->gain_trsw[i];
+ pkt_stat->rx_power[i] = (val & 0x7F) - 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);
+ }
+}
+
+static void rtw8821a_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_rx_status *rx_status)
+{
+ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
+ struct ieee80211_hdr *hdr;
+ u8 *phy_status = NULL;
+
+ memset(pkt_stat, 0, sizeof(*pkt_stat));
+
+ pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
+ pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
+ pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
+ pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
+ GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
+ pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
+ pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
+ pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
+ pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
+ pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
+ pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
+ pkt_stat->ppdu_cnt = 0;
+ pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
+ pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
+
+ /* drv_info_sz is in unit of 8-bytes */
+ pkt_stat->drv_info_sz *= 8;
+
+ /* c2h cmd pkt's rx/phy status is not interested */
+ if (pkt_stat->is_c2h)
+ return;
+
+ hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
+ pkt_stat->drv_info_sz);
+ if (pkt_stat->phy_status) {
+ phy_status = rx_desc + desc_sz + pkt_stat->shift;
+ rtw8821a_query_phy_status(rtwdev, phy_status, pkt_stat);
+ }
+
+ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
+}
+
+static void
+rtw8821a_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path,
+ u8 rs, u32 *phy_pwr_idx)
+{
+ static const u32 offset_txagc[2] = {0xc20, 0xe20};
+ 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 rtw8821a_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);
+}
+
+static void rtw8821a_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;
+
+ rtw8821a_set_tx_power_index_by_rate(rtwdev, path, rs,
+ &phy_pwr_idx);
+ }
+
+ rtw8821a_tx_power_training(rtwdev, hal->current_band_width,
+ hal->current_channel, path);
+ }
+}
+
+static void rtw8821a_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 = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
+ dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
+ dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
+ dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
+ dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt);
+ 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 = FIELD_GET(GENMASK(15, 0), cca32_cnt);
+ 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_RXDESC, BIT(15));
+ rtw_write32_set(rtwdev, REG_RXDESC, BIT(15));
+ rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
+ rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
+}
+
+#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_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]);
+}
+
+static void rtw8821a_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]);
+}
+
+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, 0xc80, 0x0);
+ rtw_write32(rtwdev, 0xc84, 0x0);
+ rtw_write32(rtwdev, 0xc88, 0x0);
+ rtw_write32(rtwdev, 0xc8c, 0x3c000000);
+ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
+ rtw_write32(rtwdev, 0xc94, 0x00000000);
+ rtw_write32(rtwdev, 0xcc4, 0x20040000);
+ rtw_write32(rtwdev, 0xcc8, 0x20000000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x0);
+}
+
+static void rtw8821a_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]);
+}
+
+static void rtw8821a_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);
+}
+
+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, 0xcc4, 0x20040000);
+ rtw_write32(rtwdev, 0xcc8, 0x20000000);
+ rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y);
+ rtw_write32_mask(rtwdev, 0xcd4, 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 <= 2; k++) {
+ switch (k) {
+ case 0:
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, 0xc80, 0x18008c38);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x38008c38);
+ rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0);
+ break;
+ case 1:
+ rtw_write32_mask(rtwdev, 0xc80, BIT(28), 0x0);
+ rtw_write32_mask(rtwdev, 0xc84, BIT(28), 0x0);
+ rtw_write32_mask(rtwdev, 0xce8, 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, 0xc80, 0x18008c20);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x38008c20);
+ rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, 0xce8, 0x3fff0000,
+ tx_dt[cal] & 0x00003fff);
+ break;
+ }
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+ cal_retry = 0;
+ while (1) {
+ /* one shot */
+ rtw_write32(rtwdev, 0x980, 0xfa000000);
+ rtw_write32(rtwdev, 0x980, 0xf8000000);
+
+ mdelay(10);
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ delay_count = 0;
+ while (1) {
+ iqk_ready = rtw_read32_mask(rtwdev, 0xd00, 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 || delay_count > 20)
+ break;
+
+ mdelay(1);
+ delay_count++;
+ }
+
+ if (delay_count < 20) {
+ /* ============TXIQK Check============== */
+ tx_fail = rtw_read32_mask(rtwdev, 0xd00, 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, 0xd00,
+ 0x07ff0000);
+ vdf_x[k] <<= 21;
+
+ rtw_write32(rtwdev, REG_RFECTL_A,
+ 0x04000000);
+ vdf_y[k] = rtw_read32_mask(rtwdev, 0xd00,
+ 0x07ff0000);
+ vdf_y[k] <<= 21;
+
+ *tx0iqkok = true;
+ break;
+ }
+
+ rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0);
+ rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200);
+
+ *tx0iqkok = false;
+ cal_retry++;
+ if (cal_retry == 10)
+ break;
+ } else { /* If 20ms No Result, then cal_retry++ */
+ *tx0iqkok = false;
+ cal_retry++;
+ if (cal_retry == 10)
+ break;
+ }
+ }
+ }
+
+ 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, 0xc80, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x38008c10);
+ rtw_write32(rtwdev, 0xcb8, 0x00100000);
+
+ cal_retry = 0;
+ while (1) {
+ /* one shot */
+ rtw_write32(rtwdev, 0x980, 0xfa000000);
+ rtw_write32(rtwdev, 0x980, 0xf8000000);
+
+ mdelay(10);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ delay_count = 0;
+ while (1) {
+ iqk_ready = rtw_read32_mask(rtwdev, 0xd00, 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 || delay_count > 20)
+ break;
+
+ mdelay(1);
+ delay_count++;
+ }
+
+ if (delay_count < 20) {
+ /* ============TXIQK Check============== */
+ tx_fail = rtw_read32_mask(rtwdev, 0xd00, 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, 0xd00,
+ 0x07ff0000);
+ tx_x0[cal] <<= 21;
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
+ tx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00,
+ 0x07ff0000);
+ tx_y0[cal] <<= 21;
+
+ *tx0iqkok = true;
+ break;
+ }
+
+ rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0);
+ rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200);
+
+ *tx0iqkok = false;
+ cal_retry++;
+ if (cal_retry == 10)
+ break;
+ } else { /* If 20ms No Result, then cal_retry++ */
+ *tx0iqkok = false;
+ cal_retry++;
+ if (cal_retry == 10)
+ break;
+ }
+ }
+}
+
+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);
+
+ cal_retry = 0;
+ while (1) {
+ /* one shot */
+ rtw_write32(rtwdev, 0x980, 0xfa000000);
+ rtw_write32(rtwdev, 0x980, 0xf8000000);
+
+ mdelay(10);
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+
+ delay_count = 0;
+ while (1) {
+ iqk_ready = rtw_read32_mask(rtwdev, 0xd00, 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 || delay_count > 20)
+ break;
+
+ mdelay(1);
+ delay_count++;
+ }
+
+ if (delay_count < 20) {
+ /* ============RXIQK Check============== */
+ rx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(11));
+ if (!rx_fail) {
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
+ rx_x0[cal] = rtw_read32_mask(rtwdev, 0xd00,
+ 0x07ff0000);
+ rx_x0[cal] <<= 21;
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
+ rx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00,
+ 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;
+ cal_retry++;
+ if (cal_retry == 10)
+ break;
+ } else { /* If 20ms No Result, then cal_retry++ */
+ *rx0iqkok = false;
+ cal_retry++;
+ if (cal_retry == 10)
+ break;
+ }
+ }
+}
+
+static bool rtw8821a_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;
+}
+
+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 = 0;
+ 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;
+
+ while (cal < CAL_NUM_8821A) {
+ /* 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, 0xc00, 0xf, 0x4);
+
+ /* LOK setting */
+
+ /* 1. DAC/ADC sampling rate (160 MHz) */
+ rtw_write32_mask(rtwdev, 0xc5c, 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, 0x65, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, RFREG_MASK, 0x8a001);
+ rtw_write32(rtwdev, 0x90c, 0x00008000);
+ rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1);
+ /* TX (X,Y) */
+ rtw_write32(rtwdev, 0x978, 0x29002000);
+ /* RX (X,Y) */
+ rtw_write32(rtwdev, 0x97c, 0xa9002000);
+ /* [0]:AGC_en, [15]:idac_K_Mask */
+ rtw_write32(rtwdev, 0x984, 0x00462910);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ if (efuse->ext_pa_5g)
+ rtw_write32(rtwdev, 0xc88, 0x821403f7);
+ else
+ rtw_write32(rtwdev, 0xc88, 0x821403f4);
+
+ if (hal->current_band_type == RTW_BAND_5G)
+ rtw_write32(rtwdev, 0xc8c, 0x68163e96);
+ else
+ rtw_write32(rtwdev, 0xc8c, 0x28163e96);
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, 0xc80, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x38008c10);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+ rtw_write32(rtwdev, 0x980, 0xfa000000);
+ rtw_write32(rtwdev, 0x980, 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, 0x58, 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, 0x65, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, RFREG_MASK, 0x8a001);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
+ rtw_write32(rtwdev, 0x90c, 0x00008000);
+ rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1);
+ /* TX (X,Y) */
+ rtw_write32(rtwdev, 0x978, 0x29002000);
+ /* RX (X,Y) */
+ rtw_write32(rtwdev, 0x97c, 0xa9002000);
+ /* [0]:AGC_en, [15]:idac_K_Mask */
+ rtw_write32(rtwdev, 0x984, 0x0046a910);
+
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+
+ if (efuse->ext_pa_5g)
+ rtw_write32(rtwdev, 0xc88, 0x821403f7);
+ else
+ rtw_write32(rtwdev, 0xc88, 0x821403e3);
+
+ if (hal->current_band_type == RTW_BAND_5G)
+ rtw_write32(rtwdev, 0xc8c, 0x40163e96);
+ else
+ rtw_write32(rtwdev, 0xc8c, 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, 0x8f, RFREG_MASK, 0x88001);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x65, RFREG_MASK, 0x931d8);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
+
+ rtw_write32_mask(rtwdev, 0x978, 0x03FF8000,
+ (tx_x0[cal] >> 21) & 0x000007ff);
+ rtw_write32_mask(rtwdev, 0x978, 0x000007FF,
+ (tx_y0[cal] >> 21) & 0x000007ff);
+ rtw_write32_mask(rtwdev, 0x978, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, 0x97c, BIT(31), 0x0);
+ rtw_write32(rtwdev, 0x90c, 0x00008000);
+ rtw_write32(rtwdev, 0x984, 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, 0xc80, 0x38008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x18008c10);
+ rtw_write32(rtwdev, 0xc88, 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, 0xc8c, 0x28161100); /* Good */
+ else
+ rtw_write32(rtwdev, 0xc8c, 0x28160d00);
+
+ rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok,
+ rx_x0[i], rx_y0[i]);
+ }
+
+ if (tx0iqkok)
+ tx_average++;
+ if (rx0iqkok)
+ rx_average++;
+
+ cal++;
+ }
+
+ /* 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 (rtw8821a_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 = rtw8821a_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 = rtw8821a_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];
+
+ rtw8821a_iqk_backup_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8821A);
+ rtw8821a_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);
+
+ rtw8821a_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);
+ rtw8821a_iqk_restore_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8821A);
+}
+
+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, 0xc80, 0x0);
+ rtw_write32(rtwdev, 0xc84, 0x0);
+ rtw_write32(rtwdev, 0xc88, 0x0);
+ rtw_write32(rtwdev, 0xc8c, 0x3c000000);
+ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1);
+ rtw_write32_mask(rtwdev, 0xcc4, BIT(18), 1);
+ rtw_write32_mask(rtwdev, 0xcc4, BIT(29), 1);
+ rtw_write32_mask(rtwdev, 0xcc8, BIT(29), 1);
+
+ rtw_write32(rtwdev, 0xe80, 0x0);
+ rtw_write32(rtwdev, 0xe84, 0x0);
+ rtw_write32(rtwdev, 0xe88, 0x0);
+ rtw_write32(rtwdev, 0xe8c, 0x3c000000);
+ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1);
+ rtw_write32_mask(rtwdev, 0xec4, BIT(18), 1);
+ rtw_write32_mask(rtwdev, 0xec4, BIT(29), 1);
+ rtw_write32_mask(rtwdev, 0xec8, 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, 0xc90, BIT(7), 0x1);
+ rtw_write32_mask(rtwdev, 0xcc4, BIT(18), 0x1);
+ rtw_write32_mask(rtwdev, 0xcc4, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, 0xcc8, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y);
+ rtw_write32_mask(rtwdev, 0xcd4, 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, 0xcd4, 0x000007ff),
+ rtw_read32_mask(rtwdev, 0xccc, 0x000007ff));
+ } break;
+ case RF_PATH_B: {
+ /* [31] = 1 --> Page C1 */
+ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, 0xe90, BIT(7), 0x1);
+ rtw_write32_mask(rtwdev, 0xec4, BIT(18), 0x1);
+ rtw_write32_mask(rtwdev, 0xec4, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, 0xec8, BIT(29), 0x1);
+ rtw_write32_mask(rtwdev, 0xecc, 0x000007ff, tx_y);
+ rtw_write32_mask(rtwdev, 0xed4, 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, 0xed4, 0x000007ff),
+ rtw_read32_mask(rtwdev, 0xecc, 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;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ bool tx0_fail = true, rx0_fail = true;
+ bool tx1_fail = true, rx1_fail = true;
+ int tx_x0, tx_y0, tx_x1, tx_y1;
+ int rx_x0, rx_y0, rx_x1, rx_y1;
+ 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, 0xc00, 0xf, 0x4);
+ rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4);
+
+ /* DAC/ADC sampling rate (160 MHz) */
+ rtw_write32_mask(rtwdev, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
+ rtw_write32_mask(rtwdev, 0xe5c, BIT(26) | BIT(25) | BIT(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, 0x65, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, 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, 0x65, RFREG_MASK, 0x931d5);
+ rtw_write_rf(rtwdev, RF_PATH_B, 0x8f, RFREG_MASK, 0x8a001);
+
+ rtw_write32(rtwdev, 0x90c, 0x00008000);
+ rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1);
+ rtw_write32_mask(rtwdev, 0xe94, BIT(0), 0x1);
+ rtw_write32(rtwdev, 0x978, 0x29002000); /* TX (X,Y) */
+ rtw_write32(rtwdev, 0x97c, 0xa9002000); /* RX (X,Y) */
+ rtw_write32(rtwdev, 0x984, 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, 0xc88, 0x821403e3);
+ rtw_write32(rtwdev, 0xe88, 0x821403e3);
+ } else {
+ rtw_write32(rtwdev, 0xc88, 0x821403f7);
+ rtw_write32(rtwdev, 0xe88, 0x821403f7);
+ }
+ } else {
+ rtw_write32(rtwdev, 0xc88, 0x821403f1);
+ rtw_write32(rtwdev, 0xe88, 0x821403f1);
+ }
+
+ if (rtwdev->hal.current_band_type == RTW_BAND_5G) {
+ rtw_write32(rtwdev, 0xc8c, 0x68163e96);
+ rtw_write32(rtwdev, 0xe8c, 0x68163e96);
+ } else {
+ rtw_write32(rtwdev, 0xc8c, 0x28163e96);
+ rtw_write32(rtwdev, 0xe8c, 0x28163e96);
+
+ if (efuse->rfe_option == 3) {
+ if (efuse->ext_pa_2g)
+ rtw_write32(rtwdev, 0xc88, 0x821403e3);
+ else
+ rtw_write32(rtwdev, 0xc88, 0x821403f7);
+ }
+ }
+
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, 0xc80, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x38008c10);
+ rtw_write32(rtwdev, 0xce8, 0x00000000);
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, 0xe80, 0x18008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xe84, 0x38008c10);
+ rtw_write32(rtwdev, 0xee8, 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, 0x980, 0xfa000000);
+ rtw_write32(rtwdev, 0x980, 0xf8000000);
+
+ mdelay(10);
+
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
+
+ delay_count = 0;
+ while (1) {
+ if (!tx0_finish)
+ iqk0_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
+ if (!tx1_finish)
+ iqk1_ready = rtw_read32_mask(rtwdev, 0xd40, BIT(10));
+ if ((iqk0_ready && iqk1_ready) || delay_count > 20)
+ break;
+
+ mdelay(1);
+ delay_count++;
+ }
+
+ 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, 0xd00, BIT(12));
+ tx1_fail = rtw_read32_mask(rtwdev, 0xd40, BIT(12));
+
+ if (!(tx0_fail || tx0_finish)) {
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);
+ tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev,
+ 0xd00,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
+ tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev,
+ 0xd00,
+ 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,
+ 0xd40,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000);
+ tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev,
+ 0xd40,
+ 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 = rtw8821a_iqk_finish(tx0_avg, 4,
+ tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0,
+ false, false);
+
+ if (tx1_avg >= 2)
+ tx1_finish = rtw8821a_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, 0x58, 0x7fe00,
+ rtw_read_rf(rtwdev, RF_PATH_A, 0x8, 0xffc00));
+ rtw_write_rf(rtwdev, RF_PATH_B, 0x58, 0x7fe00,
+ rtw_read_rf(rtwdev, RF_PATH_B, 0x8, 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, 0x8f, RFREG_MASK, 0x88001);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x65, 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, 0x8f, RFREG_MASK, 0x88001);
+ rtw_write_rf(rtwdev, RF_PATH_B, 0x65, RFREG_MASK, 0x931d1);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000);
+ }
+
+ rtw_write32_mask(rtwdev, 0x978, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, 0x97c, BIT(31), 0x0);
+ rtw_write32(rtwdev, 0x90c, 0x00008000);
+
+ if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
+ rtw_write32(rtwdev, 0x984, 0x0046a911);
+ else
+ rtw_write32(rtwdev, 0x984, 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, 0xc80, 0x38008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xc84, 0x18008c10);
+ rtw_write32(rtwdev, 0xc88, 0x82140119);
+ }
+ if (tx1_finish) {
+ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
+ rtw_write32(rtwdev, 0xe80, 0x38008c10);
+ /* RX_Tone_idx[9:0], RxK_Mask[29] */
+ rtw_write32(rtwdev, 0xe84, 0x18008c10);
+ rtw_write32(rtwdev, 0xe88, 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, 0x978, 0x03FF8000,
+ tx_x0 & 0x000007ff);
+ rtw_write32_mask(rtwdev, 0x978, 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, 0xc8c, 0x28161500);
+ else
+ rtw_write32(rtwdev, 0xc8c, 0x28160cc0);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
+ mdelay(5);
+ rtw_write32(rtwdev, 0xc8c, 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, 0x978, 0x03FF8000,
+ tx_x1 & 0x000007ff);
+ rtw_write32_mask(rtwdev, 0x978, 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, 0xe8c, 0x28161500);
+ else
+ rtw_write32(rtwdev, 0xe8c, 0x28160ca0);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);
+ mdelay(5);
+ rtw_write32(rtwdev, 0xe8c, 0x3c000000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
+ }
+
+ delay_count = 0;
+ while (1) {
+ if (!rx0_finish && tx0_finish)
+ iqk0_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
+ if (!rx1_finish && tx1_finish)
+ iqk1_ready = rtw_read32_mask(rtwdev, 0xd40, BIT(10));
+ if ((iqk0_ready && iqk1_ready) || delay_count > 20)
+ break;
+
+ mdelay(1);
+ delay_count++;
+ }
+
+ 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, 0xd00, BIT(11));
+ rx1_fail = rtw_read32_mask(rtwdev, 0xd40, 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,
+ 0xd00,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
+ rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev,
+ 0xd00,
+ 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,
+ 0xd40,
+ 0x07ff0000);
+ rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000);
+ rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev,
+ 0xd40,
+ 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 = rtw8821a_iqk_finish(rx0_avg, 4,
+ rx_x0_temp, rx_y0_temp,
+ &rx_x0, &rx_y0,
+ true, false);
+
+ if (rx1_avg >= 2)
+ rx1_finish = rtw8821a_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] = {0};
+ u32 afe_backup[AFE_REG_NUM_8812A] = {0};
+ u32 rfa_backup[RF_REG_NUM_8812A] = {0};
+ u32 rfb_backup[RF_REG_NUM_8812A] = {0};
+ u32 reg_cb8, reg_eb8;
+
+ rtw8821a_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));
+
+ rtw8821a_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);
+
+ rtw8821a_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));
+
+ rtw8821a_iqk_restore_mac_bb(rtwdev, macbb_backup,
+ backup_macbb_reg, MACBB_REG_NUM_8812A);
+}
+
+static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev)
+{
+ u8 channel = rtwdev->hal.current_channel;
+
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
+ rtw8821a_do_iqk(rtwdev);
+ } else {
+ 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_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 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, 0x765, 0x18);
+
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
+ 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, 0x765, 0x18);
+
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8,
+ BIT_MASK_RFE_SEL89, 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, 0x765, 0x18);
+
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
+ 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, 0x765, 0x18);
+
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8,
+ BIT_MASK_RFE_SEL89, 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, 0x765, 0x18);
+
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8,
+ BIT_MASK_RFE_SEL89, 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 void rtw8821a_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),
+ rtw8821a_txscale_tbl[ofdm_swing_idx]);
+}
+
+static void rtw8821a_phy_pwrtrack(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 (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) {
+ if (need_iqk)
+ rtw8812a_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];
+
+ rtw8821a_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)
+ 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;
+ }
+
+ rtw8821a_phy_pwrtrack(rtwdev);
+ dm_info->pwr_trk_triggered = false;
+}
+
+static void rtw8821a_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, 0xa0a, pd[new_lvl]);
+}
+
+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 const struct rtw_intf_phy_para usb2_param_8821a[] = {
+ {0xFFFF, 0x00,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para usb3_param_8821a[] = {
+ {0xFFFF, 0x0000,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para_table phy_para_table_8821a = {
+ .usb2_para = usb2_param_8821a,
+ .usb3_para = usb3_param_8821a,
+ .n_usb2_para = ARRAY_SIZE(usb2_param_8821a),
+ .n_usb3_para = ARRAY_SIZE(usb2_param_8821a),
+};
+
+static struct rtw_hw_reg rtw8821a_dig[] = {
+ [0] = { .addr = 0xc50, .mask = 0x7f },
+ [1] = { .addr = 0xe50, .mask = 0x7f },
+};
+
+static 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 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 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 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 struct rtw_chip_ops rtw8821a_ops = {
+ .power_on = rtw8821a_power_on,
+ .power_off = rtw8821a_power_off,
+ .phy_set_param = NULL,
+ .read_efuse = rtw8821a_read_efuse,
+ .query_rx_desc = rtw8821a_query_rx_desc,
+ .set_channel = rtw8821a_set_channel,
+ .mac_init = NULL,
+ .read_rf = rtw8821a_phy_read_rf,
+ .write_rf = rtw_phy_write_rf_reg_sipi,
+ .set_antenna = NULL,
+ .set_tx_power_index = rtw8821a_set_tx_power_index,
+ .cfg_ldo25 = rtw8821a_cfg_ldo25,
+ .efuse_grant = rtw8821a_efuse_grant,
+ .false_alarm_statistics = rtw8821a_false_alarm_statistics,
+ .phy_calibration = rtw8821a_phy_calibration,
+ .cck_pd_set = rtw8821a_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,
+};
+
+/* 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} }
+};
+
+static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} };
+
+/* 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 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, },
+};
+
+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 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 = &phy_para_table_8821a,
+ .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);
+
+const struct rtw_chip_info rtw8812a_hw_spec = {
+ .ops = &rtw8821a_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_8821a,
+ .prioq_addrs = &prioq_addrs_8821a,
+ .intf_table = &phy_para_table_8821a,
+ .dig = rtw8821a_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_8821a,
+ .bt_rssi_step = bt_rssi_step_8821a,
+ .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_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 = 0,
+ .afh_5g = NULL,
+
+ .coex_info_hw_regs_num = 0,
+ .coex_info_hw_regs = NULL,
+};
+EXPORT_SYMBOL(rtw8812a_hw_spec);
+
+MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin");
+MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a 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..7f1c2d2eb6d2
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
@@ -0,0 +1,385 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#ifndef __RTW8821A_H__
+#define __RTW8821A_H__
+
+#include <asm/byteorder.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];
+};
+
+struct rtw8812au_efuse {
+ u8 vid[2]; /* 0xd0 */
+ u8 pid[2]; /* 0xd2 */
+ u8 res0[3];
+ u8 mac_addr[ETH_ALEN]; /* 0xd7 */
+ u8 res1[291];
+};
+
+struct rtw8821a_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 rtw8821a_efuse) == 512);
+
+extern const struct rtw_chip_info rtw8821a_hw_spec;
+extern const struct rtw_chip_info rtw8812a_hw_spec;
+
+#define BIT_FEN_USBA BIT(2)
+#define BIT_FEN_PCIEA BIT(6)
+#define WLAN_SLOT_TIME 0x09
+#define WLAN_PIFS_TIME 0x19
+#define WLAN_SIFS_CCK_CONT_TX 0xA
+#define WLAN_SIFS_OFDM_CONT_TX 0xE
+#define WLAN_SIFS_CCK_TRX 0x10
+#define WLAN_SIFS_OFDM_TRX 0x10
+#define WLAN_VO_TXOP_LIMIT 0x186
+#define WLAN_VI_TXOP_LIMIT 0x3BC
+#define WLAN_RDG_NAV 0x05
+#define WLAN_TXOP_NAV 0x1B
+#define WLAN_CCK_RX_TSF 0x30
+#define WLAN_OFDM_RX_TSF 0x30
+#define WLAN_TBTT_PROHIBIT 0x04
+#define WLAN_TBTT_HOLD_TIME 0x064
+#define WLAN_DRV_EARLY_INT 0x04
+#define WLAN_BCN_DMA_TIME 0x02
+
+#define WLAN_RX_FILTER0 0x0FFFFFFF
+#define WLAN_RX_FILTER2 0xFFFF
+#define WLAN_RCR_CFG 0xE400220E
+#define WLAN_RXPKT_MAX_SZ 12288
+#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9)
+
+#define WLAN_AMPDU_MAX_TIME 0x70
+#define WLAN_RTS_LEN_TH 0xFF
+#define WLAN_RTS_TX_TIME_TH 0x08
+#define WLAN_MAX_AGG_PKT_LIMIT 0x20
+#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20
+#define FAST_EDCA_VO_TH 0x06
+#define FAST_EDCA_VI_TH 0x06
+#define FAST_EDCA_BE_TH 0x06
+#define FAST_EDCA_BK_TH 0x06
+#define WLAN_BAR_RETRY_LIMIT 0x01
+#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08
+
+#define WLAN_TX_FUNC_CFG1 0x30
+#define WLAN_TX_FUNC_CFG2 0x30
+#define WLAN_MAC_OPT_NORM_FUNC1 0x98
+#define WLAN_MAC_OPT_LB_FUNC1 0x80
+#define WLAN_MAC_OPT_FUNC2 0xb0810041
+
+#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
+ (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
+ (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
+ (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
+
+#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
+ (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
+
+#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
+#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
+#define WLAN_PRE_TXCNT_TIME_TH 0x1E4
+
+struct rtw8821a_phy_status_rpt {
+ /* DWORD 0 */
+ u8 gain_trsw[2]; /* path-A and path-B { TRSW, gain[6:0] } */
+ u8 chl_num_lsb; /* channel number[7:0] */
+#ifdef __LITTLE_ENDIAN
+ u8 chl_num_msb:2; /* channel number[9:8] */
+ u8 sub_chnl:4; /* sub-channel location[3:0] */
+ u8 r_rfmod:2; /* RF mode[1:0] */
+#else
+ u8 r_rfmod:2;
+ u8 sub_chnl:4;
+ u8 chl_num_msb:2;
+#endif
+
+ /* DWORD 1 */
+ u8 pwdb_all; /* CCK signal quality / OFDM pwdb all */
+ s8 cfosho[2]; /* CCK AGC report and CCK_BB_Power */
+ /* OFDM path-A and path-B short CFO */
+#ifdef __LITTLE_ENDIAN
+ u8 resvd_0:6;
+ u8 bt_rf_ch_msb:2; /* 8812A: 2'b0 8814A: bt rf channel keep[7:6] */
+#else
+ u8 bt_rf_ch_msb:2;
+ u8 resvd_0:6;
+#endif
+
+ /* DWORD 2 */
+#ifdef __LITTLE_ENDIAN
+ u8 ant_div_sw_a:1; /* 8812A: ant_div_sw_a 8814A: 1'b0 */
+ u8 ant_div_sw_b:1; /* 8812A: ant_div_sw_b 8814A: 1'b0 */
+ u8 bt_rf_ch_lsb:6; /* 8812A: 6'b0 8814A: bt rf channel keep[5:0] */
+#else
+ u8 bt_rf_ch_lsb:6;
+ u8 ant_div_sw_b:1;
+ u8 ant_div_sw_a:1;
+#endif
+ s8 cfotail[2]; /* path-A and path-B CFO tail */
+ u8 pcts_msk_rpt_0; /* PCTS mask report[7:0] */
+
+ /* DWORD 3 */
+ u8 pcts_msk_rpt_1; /* PCTS mask report[15:8] */
+ s8 rxevm[2]; /* stream 1 and stream 2 RX EVM */
+ s8 rxsnr[2]; /* path-A and path-B RX SNR */
+
+ /* DWORD 4 */
+ /* rxsnr[1] */
+ u8 pcts_msk_rpt_2; /* PCTS mask report[23:16] */
+#ifdef __LITTLE_ENDIAN
+ u8 pcts_msk_rpt_3:6; /* PCTS mask report[29:24] */
+ u8 pcts_rpt_valid:1;
+ u8 resvd_1:1; /* 1'b0 */
+#else
+ u8 resvd_1:1;
+ u8 pcts_rpt_valid:1;
+ u8 pcts_msk_rpt_3:6;
+#endif
+ s8 rxevm_cd[2]; /* 8812A: 16'b0 8814A: stream 3 and stream 4 RX EVM */
+
+ /* DWORD 5 */
+ /* rxevm_cd[1] */
+ u8 csi_current[2]; /* 8812A: stream 1 and 2 CSI */
+ /* 8814A: path-C and path-D RX SNR */
+ u8 gain_trsw_cd[2]; /* path-C and path-D { TRSW, gain[6:0] } */
+
+ /* DWORD 6 */
+ /* gain_trsw_cd[1] */
+ s8 sigevm; /* signal field EVM */
+#ifdef __LITTLE_ENDIAN
+ u8 antidx_antc:3; /* 8812A: 3'b0 8814A: antidx_antc[2:0] */
+ u8 antidx_antd:3; /* 8812A: 3'b0 8814A: antidx_antd[2:0] */
+ u8 dpdt_ctrl_keep:1; /* 8812A: 1'b0 8814A: dpdt_ctrl_keep */
+ u8 gnt_bt_keep:1; /* 8812A: 1'b0 8814A: GNT_BT_keep */
+#else
+ u8 gnt_bt_keep:1;
+ u8 dpdt_ctrl_keep:1;
+ u8 antidx_antd:3;
+ u8 antidx_antc:3;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u8 antidx_anta:3; /* antidx_anta[2:0] */
+ u8 antidx_antb:3; /* antidx_antb[2:0] */
+ u8 hw_antsw_occur:2; /* 1'b0 */
+#else
+ u8 hw_antsw_occur:2;
+ u8 antidx_antb:3;
+ u8 antidx_anta:3;
+#endif
+};
+
+#define REG_SYS_CTRL 0x000
+#define BIT_FEN_EN BIT(26)
+#define REG_APS_FSMCO 0x04
+#define APS_FSMCO_MAC_ENABLE BIT(8)
+#define APS_FSMCO_MAC_OFF BIT(9)
+#define APS_FSMCO_HW_POWERDOWN BIT(15)
+#define REG_ACLK_MON 0x3e
+#define REG_RF_B_CTRL 0x76
+#define REG_HIMR0 0xb0
+#define REG_HISR0 0xb4
+#define REG_HIMR1 0xb8
+#define REG_HISR1 0xbc
+#define HCI_TXDMA_EN BIT(0)
+#define HCI_RXDMA_EN BIT(1)
+#define TXDMA_EN BIT(2)
+#define RXDMA_EN BIT(3)
+#define PROTOCOL_EN BIT(4)
+#define SCHEDULE_EN BIT(5)
+#define MACTXEN BIT(6)
+#define MACRXEN BIT(7)
+#define ENSWBCN BIT(8)
+#define ENSEC BIT(9)
+#define CALTMR_EN BIT(10) /* 32k CAL TMR enable */
+#define REG_MSR 0x102
+#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 REG_LLT_INIT 0x01E0
+#define BIT_LLT_WRITE_ACCESS BIT(30)
+#define REG_DWBCN1_CTRL 0x228
+#define REG_EARLY_MODE_CONTROL 0x2bc
+#define REG_TXPKT_EMPTY 0x41a
+#define REG_AMPDU_MAX_LENGTH 0x458
+#define REG_FAST_EDCA_CTRL 0x460
+#define REG_TX_RPT_CTRL 0x4ec
+#define REG_TX_RPT_TIME 0x4f0
+#define REG_BCNTCFG 0x510
+#define REG_INIRTS_RATE_SEL 0x0480
+#define REG_HTSTFWT 0x800
+#define REG_CCK_RPT_FORMAT 0x804
+#define BIT_CCK_RPT_FORMAT BIT(16)
+#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_BWINDICATION 0x834
+#define REG_CCA2ND 0x838
+#define REG_L1WT 0x83c
+#define REG_L1PKWT 0x840
+#define REG_L1PKTH 0x848
+#define REG_MRC 0x850
+#define REG_CLKTRK 0x860
+#define REG_ADCCLK 0x8ac
+#define REG_HSSI_READ 0x8b0
+#define REG_FPGA0_XCD_RF_PARA 0x8b4
+#define REG_ADC160 0x8c4
+#define REG_ADC40 0x8c8
+#define REG_CHFIR 0x8f0
+#define REG_ANTSEL_SW 0x900
+#define REG_SINGLE_TONE_CONT_TX 0x914
+#define REG_CDDTXP 0x93c
+#define REG_TXPSEL1 0x940
+#define REG_ACBB0 0x948
+#define REG_ACBBRXFIR 0x94c
+#define REG_ACGG2TBL 0x958
+#define REG_FAS 0x9a4
+#define REG_RXSB 0xa00
+#define REG_CCK_RX 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
+#define WLG_LNA 0x7532
+#define REG_ENRXCCA 0xa84
+#define BTG_CCA 0x0e
+#define WLG_CCA 0x12
+#define REG_PWRTH2 0xaa8
+#define REG_CSRATIO 0xaaa
+#define REG_TXFILTER 0xaac
+#define REG_CNTRST 0xb58
+#define REG_AGCTR_A 0xc08
+#define REG_RX_IQC_AB_A 0xc10
+#define REG_TXSCALE_A 0xc1c
+#define BB_SWING_MASK GENMASK(31, 21)
+#define REG_TXDFIR 0xc20
+#define REG_RXIGI_A 0xc50
+#define REG_TX_PWR_TRAINING_A 0xc54
+#define REG_AFE_PWR1_A 0xc60
+#define REG_AFE_PWR2_A 0xc64
+#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0xc68
+#define REG_LSSI_WRITE_A 0xc90
+#define REG_TXAGCIDX 0xc94
+#define REG_TRSW 0xca0
+#define REG_RFESEL0 0xcb0
+#define REG_RFE_PINMUX_A 0xcb0
+#define REG_RFESEL8 0xcb4
+#define REG_RFE_INV_A 0xcb4
+#define RFE_INV_MASK 0x3ff00000
+#define REG_RFECTL_A 0xcb8
+#define B_BTG_SWITCH BIT(16)
+#define B_CTRL_SWITCH BIT(18)
+#define B_WL_SWITCH (BIT(20) | BIT(22))
+#define B_WLG_SWITCH BIT(21)
+#define B_WLA_SWITCH BIT(23)
+#define REG_RFEINV 0xcbc
+#define REG_PI_READ_A 0xd04
+#define REG_SI_READ_A 0xd08
+#define REG_PI_READ_B 0xd44
+#define REG_SI_READ_B 0xd48
+#define REG_AGCTR_B 0xe08
+#define REG_RX_IQC_AB_B 0xe10
+#define REG_TXSCALE_B 0xe1c
+#define REG_RXIGI_B 0xe50
+#define REG_TX_PWR_TRAINING_B 0xe54
+#define REG_AFE_PWR1_B 0xe60
+#define REG_AFE_PWR2_B 0xe64
+#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0xe68
+#define REG_LSSI_WRITE_B 0xe90
+#define REG_RFE_PINMUX_B 0xeb0
+#define REG_RFE_INV_B 0xeb4
+#define REG_RFECTL_B 0xeb8
+#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
+#define REG_IQKFAILMSK 0x1bf0
+#define BIT_MASK_R_RFE_SEL_15 GENMASK(31, 28)
+#define BIT_SDIO_INT BIT(18)
+#define BT_CNT_ENABLE 0x1
+#define BIT_BCN_QUEUE BIT(3)
+#define BCN_PRI_EN 0x1
+#define PTA_CTRL_PIN 0x66
+#define DPDT_CTRL_PIN 0x77
+#define ANTDIC_CTRL_PIN 0x88
+#define REG_CTRL_TYPE 0x67
+#define BIT_CTRL_TYPE1 BIT(5)
+#define BIT_CTRL_TYPE2 BIT(4)
+#define CTRL_TYPE_MASK GENMASK(15, 8)
+#define REG_USB_HRPWM 0xfe58
+
+#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8))
+#define RF18_BAND_2G (0)
+#define RF18_BAND_5G (BIT(16) | BIT(8))
+#define RF18_CHANNEL_MASK (MASKBYTE0)
+#define RF18_RFSI_MASK (BIT(18) | BIT(17))
+#define RF18_RFSI_GE (BIT(17))
+#define RF18_RFSI_GT (BIT(18))
+#define RF18_BW_MASK (BIT(11) | BIT(10))
+#define RF18_BW_20M (BIT(11) | BIT(10))
+#define RF18_BW_40M (BIT(10))
+#define RF18_BW_80M (0)
+#define RF_MODE_TABLE_ADDR 0x30
+#define RF_MODE_TABLE_DATA0 0x31
+#define RF_MODE_TABLE_DATA1 0x32
+#define RF_LCK 0xb4
+
+#endif
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 19/20] wifi: rtw88: Add rtw8821au.c and rtw8812au.c
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (17 preceding siblings ...)
2024-08-11 21:07 ` [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h} Bitterblue Smith
@ 2024-08-11 21:08 ` Bitterblue Smith
2024-08-15 7:58 ` Ping-Ke Shih
2024-08-11 21:11 ` [PATCH 20/20] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers Bitterblue Smith
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:08 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih
These are the entry points for the new modules rtw88_8821au
(RTL8821AU/RTL8811AU) and rtw88_8812au (RTL8812AU).
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
.../net/wireless/realtek/rtw88/rtw8812au.c | 28 +++++++++++++++++++
.../net/wireless/realtek/rtw88/rtw8821au.c | 28 +++++++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812au.c b/drivers/net/wireless/realtek/rtw88/rtw8812au.c
new file mode 100644
index 000000000000..9997edd386aa
--- /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) 2018-2019 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_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/rtw8821au.c b/drivers/net/wireless/realtek/rtw88/rtw8821au.c
new file mode 100644
index 000000000000..9af5dcc6a86c
--- /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) 2018-2019 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");
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 20/20] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
` (18 preceding siblings ...)
2024-08-11 21:08 ` [PATCH 19/20] wifi: rtw88: Add rtw8821au.c and rtw8812au.c Bitterblue Smith
@ 2024-08-11 21:11 ` Bitterblue Smith
2024-08-15 8:01 ` Ping-Ke Shih
19 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-11 21:11 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
Cc: Ping-Ke Shih, Zenm Chen, Christian Hewitt, Nick Morrow
These are older Wifi 5 chips. RTL8821AU is 1x1, with or without
Bluetooth. RTL8812AU is 2x2, without Bluetooth.
Beamforming is not implemented. It looks like these chips need a
different implementation than what is in bf.c.
Speed tests with RTL8821AU: 137 Mbps download, 144 Mbps upload.
Speed tests with RTL8812AU: 344 Mbps download, 387 Mbps upload.
RTL8812AU should be faster, but my router is currently limited to
transmitting only one spatial stream due to a kernel bug.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/Kconfig | 25 +++++++++++++++++++++
drivers/net/wireless/realtek/rtw88/Makefile | 9 ++++++++
2 files changed, 34 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 02b0d698413b..f4746166443f 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -43,6 +43,9 @@ config RTW88_8723D
config RTW88_8821C
tristate
+config RTW88_8821A
+ tristate
+
config RTW88_8822BE
tristate "Realtek 8822BE PCI wireless network adapter"
depends on PCI
@@ -189,6 +192,28 @@ config RTW88_8821CU
802.11ac USB wireless network adapter
+config RTW88_8821AU
+ tristate "Realtek 8821AU 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 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_8821A
+ 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..2827e6373fbc 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -77,6 +77,15 @@ rtw88_8821cs-objs := rtw8821cs.o
obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o
rtw88_8821cu-objs := rtw8821cu.o
+obj-$(CONFIG_RTW88_8821A) += rtw88_8821a.o
+rtw88_8821a-objs := rtw8821a.o rtw8821a_table.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
--
2.46.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* RE: [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips
2024-08-11 20:54 ` [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips Bitterblue Smith
@ 2024-08-15 6:10 ` Ping-Ke Shih
2024-08-19 17:51 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:10 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> RTL8821AU and RTL8812AU don't support this. They hit the "failed to read
> hw feature report" error.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> drivers/net/wireless/realtek/rtw88/main.c | 4 ++++
> drivers/net/wireless/realtek/rtw88/main.h | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
> 7 files changed, 10 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> index ff045dfdca4a..aeb21ac25e2e 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -1923,6 +1923,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
> u8 bw;
> int i;
>
> + if (!rtwdev->chip->hw_feature_report)
> + goto print_hw_cap;
Since chips don't support of hw_feature_report, printing hw capabilities seems
useless. Just 'return'?
> +
> id = rtw_read8(rtwdev, REG_C2HEVT);
> if (id != C2H_HW_FEATURE_REPORT) {
> rtw_err(rtwdev, "failed to read hw feature report\n");
> @@ -1947,6 +1950,7 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
> efuse->hw_cap.nss > rtwdev->hal.rf_path_num)
> efuse->hw_cap.nss = rtwdev->hal.rf_path_num;
>
> +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,
[...]
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-11 20:55 ` [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes Bitterblue Smith
@ 2024-08-15 6:14 ` Ping-Ke Shih
2024-08-19 17:52 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:14 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
> Avoid the "invalid ra report c2h length" error.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
> drivers/net/wireless/realtek/rtw88/main.h | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
> 7 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
> index 782f3776e0a0..ac53e3e30af0 100644
> --- a/drivers/net/wireless/realtek/rtw88/fw.c
> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
>
> rate = GET_RA_REPORT_RATE(ra_data->payload);
> sgi = GET_RA_REPORT_SGI(ra_data->payload);
> - bw = GET_RA_REPORT_BW(ra_data->payload);
> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
> + bw = si->bw_mode;
> + else
> + bw = GET_RA_REPORT_BW(ra_data->payload);
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 04/20] wifi: rtw88: Extend the init table parsing for RTL8812AU
2024-08-11 20:55 ` [PATCH 04/20] wifi: rtw88: Extend the init table parsing for RTL8812AU Bitterblue Smith
@ 2024-08-15 6:27 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:27 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> The chips supported so far only use the first condition, and so the
> parsing code ignores the second condition. RTL8812AU's init tables use
> the second condition also. Make the parsing code check it.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> drivers/net/wireless/realtek/rtw88/main.h | 15 ++++++
> drivers/net/wireless/realtek/rtw88/phy.c | 57 ++++++++++++++++++++---
> 2 files changed, 66 insertions(+), 6 deletions(-)
>
[...]
> @@ -1042,6 +1045,7 @@ 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_cond2 cond2 = {0};
'= {}'
I guess you imitate above declaration. Please change both to '= {}'.
>
> cond.cut = hal->cut_version ? hal->cut_version : 15;
> cond.pkg = pkg ? pkg : 15;
[...]
> @@ -1091,6 +1134,7 @@ 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_cond2 pos_cond2 = {0};
ditto. '={}'
> bool is_matched = true, is_skipped = false;
>
> BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair));
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL
2024-08-11 20:57 ` [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL Bitterblue Smith
@ 2024-08-15 6:33 ` Ping-Ke Shih
2024-08-19 17:53 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:33 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> RTL8821A doesn't have this. Trying to use it results in error messages,
> so don't try if ltecoex_addr is NULL.
In short term, it is fine to avoid these messages, but we need BT-coexistence
for RTL8821A if we want better user experience with BT.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU
2024-08-11 20:54 ` [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU Bitterblue Smith
@ 2024-08-15 6:34 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:34 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> Add 8821A and 8812A chip type enums.
>
> Add cck_high_power member to struct rtw_hal. This will be used to
> calculate the RX signal strength.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 07/20] wifi: rtw88: Enable data rate fallback for older chips
2024-08-11 20:59 ` [PATCH 07/20] wifi: rtw88: Enable data rate fallback for older chips Bitterblue Smith
@ 2024-08-15 6:46 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:46 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> RTL8811AU fails to perform the 4-way handshake when the AP is too far
> because it transmits the EAPOL frames at MCS9 and when that doesn't
> work it retries 48 times with the same rate, to no avail.
>
> Retrying 48 times with the same rate seems pointless. Set the
> appropriate field in the TX descriptor to allow it to use lower rates
> when retrying.
>
> Set it for RTL8723D and RTL8703B because they interpret this field the
> same way as RTL8811A.
>
> The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in
> the TX descriptor differently, so leave it alone for those chips.
Please fill '.old_datarate_fb_limit = false' for these chips. It will be easier
to know they are not missing.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 08/20] wifi: rtw88: Make txagc_remnant_ofdm an array
2024-08-11 21:00 ` [PATCH 08/20] wifi: rtw88: Make txagc_remnant_ofdm an array Bitterblue Smith
@ 2024-08-15 6:50 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:50 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> txagc_remnant_ofdm member of struct rtw_dm_info should be different for
> each RF path, so make it an array of size RTW_RF_PATH_MAX (4).
>
> Until now all the chips using this had only one RF path, but RTL8812AU
> has two, and RTL8814AU has four.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 09/20] wifi: rtw88: Support TX page sizes bigger than 128
2024-08-11 21:00 ` [PATCH 09/20] wifi: rtw88: Support TX page sizes bigger than 128 Bitterblue Smith
@ 2024-08-15 6:52 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 6:52 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> All the chips supported so far have a TX page size of 128 bytes.
>
> Change the type of the page_size member of struct rtw_chip_info from u8
> to u16 in order to support RTL8821AU (page size of 256 bytes) and
> RTL8812AU (page size of 512 bytes). Also change the types of several
> related variables and function parameters from u8 to u16.
>
> The TX page size is used, among other things, to construct the beacon,
> null data, QOS null data, and PS poll templates which are uploaded to
> the chip's reserved page. Each template needs to be aligned on a
> multiple of the TX page size. Power saving can't work if the TX page
> size is wrong.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 10/20] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def
2024-08-11 21:01 ` [PATCH 10/20] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def Bitterblue Smith
@ 2024-08-15 7:00 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:00 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> RTL8812AU uses one set of TX power tracking tables for RFE 3, and
> another set for everything else.
>
> Move pwr_track_tbl from struct rtw_chip_info to struct rtw_rfe_def in
> order to load the right set of tables for each RFE (RF front end) type.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 11/20] wifi: rtw88: usb: Set pkt_info.ls for the reserved page
2024-08-11 21:02 ` [PATCH 11/20] wifi: rtw88: usb: Set pkt_info.ls for the reserved page Bitterblue Smith
@ 2024-08-15 7:07 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:07 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> "ls" meaning "last segment". Without this RTL8812AU can't upload the
> reserved page in USB 2 mode. (Somehow it's fine in USB 3 mode.)
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 12/20] wifi: rtw88: Detect beacon loss with chips other than 8822c
2024-08-11 21:02 ` [PATCH 12/20] wifi: rtw88: Detect beacon loss with chips other than 8822c Bitterblue Smith
@ 2024-08-15 7:16 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:16 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> The driver is supposed to avoid entering LPS (power saving) when there
> is beacon loss, but only RTL8822C detects the beacon loss (because it
> has beacon filtering in the firmware).
>
> Detect beacon loss with the other chips by checking if we received less
> than half the expected number of beacons in the last 2-second interval.
>
> This gets rid of the occasional "failed to get tx report from firmware"
> warnings with RTL8821AU. It may also avoid some disconnections.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> drivers/net/wireless/realtek/rtw88/main.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> index 3806e57400fb..62d9abc04a34 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -254,6 +254,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
> if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
> goto unlock;
>
> + int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt;
> +
Though currently compiler doesn't warn arbitrarily declare variables, we still
should declare it on top of functions.
> /* make sure BB/RF is working for dynamic mech */
> rtw_leave_lps(rtwdev);
> rtw_coex_wl_status_check(rtwdev);
> @@ -270,6 +272,15 @@ static void rtw_watch_dog_work(struct work_struct *work)
> */
> rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
>
> + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) &&
> + data.rtwvif) {
> + int beacon_int = rtwvif_to_vif(data.rtwvif)->bss_conf.beacon_int;
> + int watchdog_delay = 2000000 / 1024; /* TU */
> + int expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int);
> +
> + rtwdev->beacon_loss = received_beacons < expected_beacons / 2;
> + }
> +
Please move to an individual function such as rtw_sw_beacon_loss_check().
> /* 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
> --
> 2.46.0
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 13/20] wifi: rtw88: coex: Support chips without a scoreboard
2024-08-11 21:03 ` [PATCH 13/20] wifi: rtw88: coex: Support chips without a scoreboard Bitterblue Smith
@ 2024-08-15 7:19 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:19 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> All the chips currently supported have a "scoreboard": the chip keeps
> track of certain things related to bluetooth, for example, whether
> bluetooth is active. The information can be read from register 0xaa.
>
> RTL8821AU doesn't have this. Implement bluetooth activity detection in
> rtw_coex_monitor_bt_enable() based on the bluetooth TX/RX counters.
>
> This is mostly important for RTL8811AU, the version of RTL8821AU without
> bluetooth. Without this change, the driver thinks bluetooth is active
> and the wifi speeds are low.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 14/20] wifi: rtw88: 8821a: Regularly ask for BT info updates
2024-08-11 21:04 ` [PATCH 14/20] wifi: rtw88: 8821a: Regularly ask for BT info updates Bitterblue Smith
@ 2024-08-15 7:26 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:26 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> The RTL8821AU firmware sends C2H_BT_INFO by itself when bluetooth
> headphones are connected, but not when they are disconnected. This leads
> to the coexistence code still using the A2DP algorithm long after the
> headphones are disconnected, which means the wifi speeds are much lower
> than they should be. Work around this by asking for updates every two
> seconds if the chip is RTL8821AU.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> drivers/net/wireless/realtek/rtw88/coex.c | 2 +-
> drivers/net/wireless/realtek/rtw88/coex.h | 1 +
> drivers/net/wireless/realtek/rtw88/main.c | 3 +++
> 3 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
> index 39fbc5ef82f8..91e21bdfb569 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;
> diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h
> index 57cf29da9ea4..b6400e87e78d 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);
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> index 62d9abc04a34..699870ca1a9f 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -261,6 +261,9 @@ static void rtw_watch_dog_work(struct work_struct *work)
> rtw_coex_wl_status_check(rtwdev);
> rtw_coex_query_bt_hid_list(rtwdev);
>
> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex)
> + rtw_coex_query_bt_info(rtwdev);
> +
Move to an individual function such as rtw_coex_active_query_bt_info() (maybe inline function),
and add a little bit comments to describe how we need this.
> rtw_phy_dynamic_mechanism(rtwdev);
>
> rtw_hci_dynamic_rx_agg(rtwdev,
> --
> 2.46.0
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 15/20] wifi: rtw88: 8812a: Mitigate beacon loss
2024-08-11 21:05 ` [PATCH 15/20] wifi: rtw88: 8812a: Mitigate beacon loss Bitterblue Smith
@ 2024-08-15 7:31 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:31 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> The RTL8812AU has a reception problem, maybe only in the 5 GHz band.
> Sometimes, in some positions, it stops receiving anything even though
> the distance to the AP is only ~3 meters and there are no obstacles.
> Moving it a few centimeters fixes it.
>
> Switch the initial gain to maximum coverage when there is beacon loss.
> This only helps sometimes. This is similar to what the official driver
> does.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h}
2024-08-11 21:06 ` [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h} Bitterblue Smith
@ 2024-08-15 7:53 ` Ping-Ke Shih
2024-08-16 1:19 ` Ping-Ke Shih
1 sibling, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:53 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> These contain various arrays for initialising RTL8812AU. Also TX power
> limits.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> .../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++++++++
> .../wireless/realtek/rtw88/rtw8812a_table.h | 26 +
> 2 files changed, 2838 insertions(+)
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h
>
> 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..0d005d88b0a4
> --- /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) 2018-2019 Realtek Corporation
year 2024
[...]
> +
> +const struct rtw_pwr_seq_cmd *card_enable_flow_8812a[] = {
> + trans_carddis_to_cardemu_8812a,
> + trans_cardemu_to_act_8812a,
> + NULL
> +};
> +
> +const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[] = {
> + trans_act_to_lps_8812a,
> + NULL
> +};
> +
> +const struct rtw_pwr_seq_cmd *card_disable_flow_8812a[] = {
> + trans_act_to_cardemu_8812a,
> + trans_cardemu_to_carddis_8812a,
> + NULL
> +};
> +
These three array should be 'const struct rtw_pwr_seq_cmd * const ...'.
I don't expect things in ".data" section.
$ objdump -t rtw8812a_table.o | grep "\.data"
0000000000000000 g O .data 0000000000000018 card_disable_flow_8812a
0000000000000020 g O .data 0000000000000010 enter_lps_flow_8812a
0000000000000030 g O .data 0000000000000018 card_enable_flow_8812a
[...]
> 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..15ecc72b175a
> --- /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) 2018-2019 Realtek Corporation
year 2024
> + */
> +
> +#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 *card_enable_flow_8812a[];
> +extern const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[];
> +extern const struct rtw_pwr_seq_cmd *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
> --
> 2.46.0
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 17/20] wifi: rtw88: Add rtw8821a_table.{c,h}
2024-08-11 21:06 ` [PATCH 17/20] wifi: rtw88: Add rtw8821a_table.{c,h} Bitterblue Smith
@ 2024-08-15 7:55 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:55 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> These contain various arrays for initialising RTL8821AU. Also TX power
> limits.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> .../wireless/realtek/rtw88/rtw8821a_table.c | 2350 +++++++++++++++++
> .../wireless/realtek/rtw88/rtw8821a_table.h | 21 +
> 2 files changed, 2371 insertions(+)
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h
>
> 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..32ddd460e7bb
> --- /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) 2018-2019 Realtek Corporation
year 2024
[...]
> +
> +const struct rtw_pwr_seq_cmd *card_enable_flow_8821a[] = {
> + trans_carddis_to_cardemu_8821a,
> + trans_cardemu_to_act_8821a,
> + NULL
> +};
> +
> +const struct rtw_pwr_seq_cmd *enter_lps_flow_8821a[] = {
> + trans_act_to_lps_8821a,
> + NULL
> +};
> +
> +const struct rtw_pwr_seq_cmd *card_disable_flow_8821a[] = {
> + trans_act_to_cardemu_8821a,
> + trans_cardemu_to_carddis_8821a,
> + NULL
> +};
The same as 8812A.
$ objdump -t rtw8821a_table.o | grep "\.data"
0000000000000000 g O .data 0000000000000018 card_disable_flow_8821a
0000000000000020 g O .data 0000000000000010 enter_lps_flow_8821a
0000000000000030 g O .data 0000000000000018 card_enable_flow_8821a
[...]
> 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..070ffdbcd271
> --- /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) 2018-2019 Realtek Corporation
year 2024
> + */
> +
> +#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 *card_enable_flow_8821a[];
> +extern const struct rtw_pwr_seq_cmd *enter_lps_flow_8821a[];
> +extern const struct rtw_pwr_seq_cmd *card_disable_flow_8821a[];
> +
> +extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl;
> +
> +#endif
> --
> 2.46.0
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 19/20] wifi: rtw88: Add rtw8821au.c and rtw8812au.c
2024-08-11 21:08 ` [PATCH 19/20] wifi: rtw88: Add rtw8821au.c and rtw8812au.c Bitterblue Smith
@ 2024-08-15 7:58 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 7:58 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>
> These are the entry points for the new modules rtw88_8821au
> (RTL8821AU/RTL8811AU) and rtw88_8812au (RTL8812AU).
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> .../net/wireless/realtek/rtw88/rtw8812au.c | 28 +++++++++++++++++++
> .../net/wireless/realtek/rtw88/rtw8821au.c | 28 +++++++++++++++++++
> 2 files changed, 56 insertions(+)
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c
>
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812au.c
> b/drivers/net/wireless/realtek/rtw88/rtw8812au.c
> new file mode 100644
> index 000000000000..9997edd386aa
> --- /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) 2018-2019 Realtek Corporation
Year 2024.
Please update year across whole patchset.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 20/20] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers
2024-08-11 21:11 ` [PATCH 20/20] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers Bitterblue Smith
@ 2024-08-15 8:01 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-15 8:01 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Cc: Zenm Chen, Christian Hewitt, Nick Morrow
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> These are older Wifi 5 chips. RTL8821AU is 1x1, with or without
> Bluetooth. RTL8812AU is 2x2, without Bluetooth.
>
> Beamforming is not implemented. It looks like these chips need a
> different implementation than what is in bf.c.
>
> Speed tests with RTL8821AU: 137 Mbps download, 144 Mbps upload.
> Speed tests with RTL8812AU: 344 Mbps download, 387 Mbps upload.
>
> RTL8812AU should be faster, but my router is currently limited to
> transmitting only one spatial stream due to a kernel bug.
Could you also mention operation mode (e.g. STA and AP) you have tested?
I think AP mode patch can't work for now, because I have not yet sent out
the fixes.
Patch 18/20 is quite large. Please give me some time to review.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h}
2024-08-11 21:06 ` [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h} Bitterblue Smith
2024-08-15 7:53 ` Ping-Ke Shih
@ 2024-08-16 1:19 ` Ping-Ke Shih
1 sibling, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-16 1:19 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Ping-Ke Shih wrote:
>
> > +
> > +const struct rtw_pwr_seq_cmd *card_enable_flow_8812a[] = {
> > + trans_carddis_to_cardemu_8812a,
> > + trans_cardemu_to_act_8812a,
> > + NULL
> > +};
> > +
> > +const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[] = {
> > + trans_act_to_lps_8812a,
> > + NULL
> > +};
> > +
> > +const struct rtw_pwr_seq_cmd *card_disable_flow_8812a[] = {
> > + trans_act_to_cardemu_8812a,
> > + trans_cardemu_to_carddis_8812a,
> > + NULL
> > +};
> > +
>
> These three array should be 'const struct rtw_pwr_seq_cmd * const ...'.
>
> I don't expect things in ".data" section.
>
> $ objdump -t rtw8812a_table.o | grep "\.data"
> 0000000000000000 g O .data 0000000000000018 card_disable_flow_8812a
> 0000000000000020 g O .data 0000000000000010 enter_lps_flow_8812a
> 0000000000000030 g O .data 0000000000000018 card_enable_flow_8812a
>
The existing chips have this style already, so we need additional one patch
to convert them into const first.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-08-11 21:07 ` [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h} Bitterblue Smith
@ 2024-08-16 6:06 ` Ping-Ke Shih
2024-08-27 17:52 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-16 6:06 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> These contain all the logic for the RTL8821AU and RTL8812AU chips.
>
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> drivers/net/wireless/realtek/rtw88/rtw8821a.c | 4139 +++++++++++++++++
> drivers/net/wireless/realtek/rtw88/rtw8821a.h | 385 ++
> 2 files changed, 4524 insertions(+)
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c
> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h
>
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> new file mode 100644
> index 000000000000..e72599db74ed
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> @@ -0,0 +1,4139 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +/* Copyright(c) 2018-2019 Realtek Corporation
Year 2024
[...]
> +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, 0x8bc, 0xc0000060, 0x4);
#define REG_RX_MCS_LIMIT 0x8bc
The setting value is weird to me though.
> +
> + /* RF Path_B HSSI OFF */
> + rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4);
#define REG_HSSI_WRITE_B 0xe00
> +
> + /* 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 u8 rtw8821a_get_swing_index(struct rtw_dev *rtwdev)
> +{
> + u32 swing, table_value;
> + u8 i = 0;
no need '= 0'
> +
> + swing = rtw8821a_get_bb_swing(rtwdev, rtwdev->hal.current_band_type,
> + RF_PATH_A);
> +
> + for (i = 0; i < ARRAY_SIZE(rtw8821a_txscale_tbl); i++) {
> + table_value = rtw8821a_txscale_tbl[i];
> + if (swing == table_value)
> + break;
return i;
> + }
> +
> + return i;
return ARRAY_SIZE(rtw8821a_txscale_tbl)? (but I don't like it so much)
or
return 24;
Move checking statement from callers to here.
> +}
> +
> +static void rtw8821a_pwrtrack_init(struct rtw_dev *rtwdev)
> +{
> + struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> + u8 ofdm_swing_idx;
> + u8 path;
> +
> + ofdm_swing_idx = rtw8821a_get_swing_index(rtwdev);
> +
> + if (ofdm_swing_idx >= ARRAY_SIZE(rtw8821a_txscale_tbl))
> + dm_info->default_ofdm_index = 24;
> + else
> + dm_info->default_ofdm_index = ofdm_swing_idx;
If rtw8821a_get_swing_index(rtwdev) returns 24 for the case we can't find a
match from rtw8821a_txscale_tbl[], here can be simply
dm_info->default_ofdm_index = rtw8821a_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;
> +}
> +
[...]
> +static int rtw8821a_power_on(struct rtw_dev *rtwdev)
> +{
Will the coming RTL8814AU share this flow? If so, we can move this power on
to main.c/mac.c as rtw_power_on_v1() or something else.
If we decide moving power on flow into chip specific files, the duplicate code
will become more and more. Please think about this.
> + 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.
> + */
> + rtw8812au_hw_reset(rtwdev);
> +
> + ret = rtw8812au_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 = rtw8821a_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);
> +
> + rtw8821au_init_queue_reserved_page(rtwdev);
> + rtw8821au_init_tx_buffer_boundary(rtwdev);
> + rtw8821au_init_queue_priority(rtwdev);
> +
Seemingly above flow looks common. Can it share with other chips?
[...]
> +}
> +
> +static u32 rtw8821a_phy_read_rf(struct rtw_dev *rtwdev,
> + enum rtw_rf_path rf_path, u32 addr, u32 mask)
> +{
read/write RF functions are also common for chips. Can it share with coming RTL8814A?
Move this to phy.c as v1?
> + static const u32 pi_addr[2] = { 0xc00, 0xe00 };
> + static const u32 read_addr[2][2] = {
> + { REG_SI_READ_A, REG_SI_READ_B },
> + { REG_PI_READ_A, REG_PI_READ_B }
> + };
[...]
> +
> +static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
> + struct rtw_rx_pkt_stat *pkt_stat)
> +{
> + struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> + struct rtw8821a_phy_status_rpt *phy_sts;
> + u8 lna_idx, vga_idx, cck_agc_rpt;
> + s8 rx_pwr_db, power_a, power_b;
> + const s8 min_rx_power = -120;
> + u8 rssi, val, i;
> +
> + phy_sts = (struct rtw8821a_phy_status_rpt *)phy_status;
> +
> + if (pkt_stat->rate <= DESC_RATE11M) {
> + cck_agc_rpt = phy_sts->cfosho[0];
> + lna_idx = (cck_agc_rpt & 0xE0) >> 5;
> + vga_idx = cck_agc_rpt & 0x1F;
If we remove "#ifdef __LITTLE_ENDIAN" from rtw8821a_phy_status_rpt and define
bit mask there, additionally define these bit masks and then use u8_get_bits().
By the way, shouldn't the field of 'cfosho[2]' be 'u8' instead of 's8'?
> +
> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
> + rx_pwr_db = rtw8821a_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
> + else
> + rx_pwr_db = rtw8812a_cck_rx_pwr(rtwdev, 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;
> +
> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A &&
> + !rtwdev->hal.cck_high_power) {
> + 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;
> + }
> + } else { /* OFDM rate */
> + for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) {
> + val = phy_sts->gain_trsw[i];
> + pkt_stat->rx_power[i] = (val & 0x7F) - 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);
> + }
> +}
> +
> +static void rtw8821a_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
> + struct rtw_rx_pkt_stat *pkt_stat,
> + struct ieee80211_rx_status *rx_status)
> +{
> + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
> + struct ieee80211_hdr *hdr;
> + u8 *phy_status = NULL;
> +
> + memset(pkt_stat, 0, sizeof(*pkt_stat));
> +
> + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
> + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
> + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
> + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
> + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
> + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
> + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
> + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
> + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
> + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
> + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
> + pkt_stat->ppdu_cnt = 0;
> + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
> + pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
More and more chips use these macros. Please add a patch using struct to
access these fields. More, query_rx_desc() are very similar across chips,
please move them to mac.c or phy.c as a common function.
> +
> + /* drv_info_sz is in unit of 8-bytes */
> + pkt_stat->drv_info_sz *= 8;
> +
> + /* c2h cmd pkt's rx/phy status is not interested */
> + if (pkt_stat->is_c2h)
> + return;
> +
> + hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
> + pkt_stat->drv_info_sz);
> + if (pkt_stat->phy_status) {
> + phy_status = rx_desc + desc_sz + pkt_stat->shift;
> + rtw8821a_query_phy_status(rtwdev, phy_status, pkt_stat);
> + }
> +
> + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
> +}
> +
[...]
> +
> +static void rtw8821a_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 = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> + dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
use u32_get_bits() instead.
> +
> + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
> + dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> + dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
> +
> + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
> + dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> + dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
> +
> + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
> + dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> + dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
> +
> + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
> + dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt);
> + 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 = FIELD_GET(GENMASK(15, 0), cca32_cnt);
> + 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_RXDESC, BIT(15));
> + rtw_write32_set(rtwdev, REG_RXDESC, BIT(15));
> + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
> + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
> +}
> +
[...]
> +
> +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, 0xc80, 0x0);
> + rtw_write32(rtwdev, 0xc84, 0x0);
> + rtw_write32(rtwdev, 0xc88, 0x0);
> + rtw_write32(rtwdev, 0xc8c, 0x3c000000);
> + rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
> + rtw_write32(rtwdev, 0xc94, 0x00000000);
> + rtw_write32(rtwdev, 0xcc4, 0x20040000);
> + rtw_write32(rtwdev, 0xcc8, 0x20000000);
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x0);
I think we can reuse existing definitions:
rtw8723x.h:#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
rtw8703b.h:#define REG_OFDM0_A_TX_AFE 0x0c84
rtw8723x.h:#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88
#define REG_TSSI_TRK_SW 0xc8c
rtw8821a.h:#define REG_TXAGCIDX 0xc94
#define REG_IQK_DPD_CFG 0xcc4
#define REG_CFG_PMPD 0xcc8
[...]
> +
> +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, 0xcc4, 0x20040000);
> + rtw_write32(rtwdev, 0xcc8, 0x20000000);
> + rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y);
> + rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, tx_x);
#define REG_IQC_Y 0xccc
#define REG_IQC_X 0xcd4
> +}
> +
> +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 <= 2; k++) {
'< 3' would be more intuitive, because 'k' is index of array.
> + switch (k) {
> + case 0:
> + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> + rtw_write32(rtwdev, 0xc80, 0x18008c38);
> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
> + rtw_write32(rtwdev, 0xc84, 0x38008c38);
> + rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0);
> + break;
> + case 1:
> + rtw_write32_mask(rtwdev, 0xc80, BIT(28), 0x0);
> + rtw_write32_mask(rtwdev, 0xc84, BIT(28), 0x0);
> + rtw_write32_mask(rtwdev, 0xce8, 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, 0xc80, 0x18008c20);
> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
> + rtw_write32(rtwdev, 0xc84, 0x38008c20);
> + rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x1);
> + rtw_write32_mask(rtwdev, 0xce8, 0x3fff0000,
> + tx_dt[cal] & 0x00003fff);
> + break;
> + }
> +
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
> + cal_retry = 0;
> + while (1) {
Can we replace 'while()' by 'for (cal_retry = 0; cal_retry < 10; cal_retry++)'?
> + /* one shot */
> + rtw_write32(rtwdev, 0x980, 0xfa000000);
> + rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> + mdelay(10);
> +
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +
> + delay_count = 0;
> + while (1) {
Similarly. 'for (delay_count = 0; delay_count < 20; delay_count++)'.
> + iqk_ready = rtw_read32_mask(rtwdev, 0xd00, 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 || delay_count > 20)
> + break;
> +
> + mdelay(1);
> + delay_count++;
> + }
> +
> + if (delay_count < 20) {
> + /* ============TXIQK Check============== */
> + tx_fail = rtw_read32_mask(rtwdev, 0xd00, 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, 0xd00,
> + 0x07ff0000);
> + vdf_x[k] <<= 21;
> +
> + rtw_write32(rtwdev, REG_RFECTL_A,
> + 0x04000000);
> + vdf_y[k] = rtw_read32_mask(rtwdev, 0xd00,
> + 0x07ff0000);
> + vdf_y[k] <<= 21;
> +
> + *tx0iqkok = true;
> + break;
> + }
> +
> + rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0);
> + rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200);
> +
> + *tx0iqkok = false;
> + cal_retry++;
> + if (cal_retry == 10)
> + break;
> + } else { /* If 20ms No Result, then cal_retry++ */
> + *tx0iqkok = false;
> + cal_retry++;
> + if (cal_retry == 10)
> + break;
> + }
> + }
> + }
> +
> + 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, 0xc80, 0x18008c10);
> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
> + rtw_write32(rtwdev, 0xc84, 0x38008c10);
> + rtw_write32(rtwdev, 0xcb8, 0x00100000);
> +
> + cal_retry = 0;
> + while (1) {
Ditto. 'for (cal_retry = 0; cal_retry < 10; cal_retry++)'
> + /* one shot */
> + rtw_write32(rtwdev, 0x980, 0xfa000000);
> + rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> + mdelay(10);
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +
> + delay_count = 0;
> + while (1) {
'for (delay_count = 0; delay_count < 20; delay_count++)'.
> + iqk_ready = rtw_read32_mask(rtwdev, 0xd00, 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 || delay_count > 20)
> + break;
> +
> + mdelay(1);
> + delay_count++;
> + }
> +
> + if (delay_count < 20) {
> + /* ============TXIQK Check============== */
> + tx_fail = rtw_read32_mask(rtwdev, 0xd00, 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, 0xd00,
> + 0x07ff0000);
> + tx_x0[cal] <<= 21;
> +
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
> + tx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> + 0x07ff0000);
> + tx_y0[cal] <<= 21;
> +
> + *tx0iqkok = true;
> + break;
> + }
> +
> + rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0);
> + rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200);
> +
> + *tx0iqkok = false;
> + cal_retry++;
> + if (cal_retry == 10)
> + break;
> + } else { /* If 20ms No Result, then cal_retry++ */
> + *tx0iqkok = false;
> + cal_retry++;
> + if (cal_retry == 10)
> + break;
> + }
> + }
> +}
> +
> +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);
> +
> + cal_retry = 0;
> + while (1) {
'for (cal_retry = 0; cal_retry < 10; cal_retry++)'
> + /* one shot */
> + rtw_write32(rtwdev, 0x980, 0xfa000000);
> + rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> + mdelay(10);
> +
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +
> + delay_count = 0;
> + while (1) {
'for (delay_count = 0; delay_count < 20; delay_count++)'.
> + iqk_ready = rtw_read32_mask(rtwdev, 0xd00, 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 || delay_count > 20)
> + break;
> +
> + mdelay(1);
> + delay_count++;
> + }
> +
> + if (delay_count < 20) {
> + /* ============RXIQK Check============== */
> + rx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(11));
> + if (!rx_fail) {
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
> + rx_x0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> + 0x07ff0000);
> + rx_x0[cal] <<= 21;
> +
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
> + rx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> + 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;
> + cal_retry++;
> + if (cal_retry == 10)
> + break;
> + } else { /* If 20ms No Result, then cal_retry++ */
> + *rx0iqkok = false;
> + cal_retry++;
> + if (cal_retry == 10)
> + break;
> + }
> + }
> +}
> +
> +static bool rtw8821a_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;
> +}
> +
> +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 = 0;
> + 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;
> +
> + while (cal < CAL_NUM_8821A) {
for (cal = 0; cal < CAL_NUM_8821A; cal++)
[...]
> +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: {
no need brace for 'case:'.
> + /* [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: {
ditto.
> + /* [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;
> + };
no need semicolon
> +}
> +
> +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: {
no need brace
> + /* [31] = 1 --> Page C1 */
> + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> + rtw_write32_mask(rtwdev, 0xc90, BIT(7), 0x1);
> + rtw_write32_mask(rtwdev, 0xcc4, BIT(18), 0x1);
> + rtw_write32_mask(rtwdev, 0xcc4, BIT(29), 0x1);
> + rtw_write32_mask(rtwdev, 0xcc8, BIT(29), 0x1);
> + rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y);
> + rtw_write32_mask(rtwdev, 0xcd4, 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, 0xcd4, 0x000007ff),
> + rtw_read32_mask(rtwdev, 0xccc, 0x000007ff));
> + } break;
> + case RF_PATH_B: {
ditto.
> + /* [31] = 1 --> Page C1 */
> + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> + rtw_write32_mask(rtwdev, 0xe90, BIT(7), 0x1);
> + rtw_write32_mask(rtwdev, 0xec4, BIT(18), 0x1);
> + rtw_write32_mask(rtwdev, 0xec4, BIT(29), 0x1);
> + rtw_write32_mask(rtwdev, 0xec8, BIT(29), 0x1);
> + rtw_write32_mask(rtwdev, 0xecc, 0x000007ff, tx_y);
> + rtw_write32_mask(rtwdev, 0xed4, 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, 0xed4, 0x000007ff),
> + rtw_read32_mask(rtwdev, 0xecc, 0x000007ff));
> + } break;
> + default:
> + break;
> + };
no need semicolon
> +}
> +
> +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;
> + struct rtw_efuse *efuse = &rtwdev->efuse;
> + bool tx0_fail = true, rx0_fail = true;
> + bool tx1_fail = true, rx1_fail = true;
> + int tx_x0, tx_y0, tx_x1, tx_y1;
> + int rx_x0, rx_y0, rx_x1, rx_y1;
> + 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, 0xc00, 0xf, 0x4);
> + rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4);
> +
> + /* DAC/ADC sampling rate (160 MHz) */
> + rtw_write32_mask(rtwdev, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
> + rtw_write32_mask(rtwdev, 0xe5c, BIT(26) | BIT(25) | BIT(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, 0x65, RFREG_MASK, 0x931d5);
> + rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, 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, 0x65, RFREG_MASK, 0x931d5);
> + rtw_write_rf(rtwdev, RF_PATH_B, 0x8f, RFREG_MASK, 0x8a001);
> +
> + rtw_write32(rtwdev, 0x90c, 0x00008000);
> + rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1);
> + rtw_write32_mask(rtwdev, 0xe94, BIT(0), 0x1);
> + rtw_write32(rtwdev, 0x978, 0x29002000); /* TX (X,Y) */
> + rtw_write32(rtwdev, 0x97c, 0xa9002000); /* RX (X,Y) */
> + rtw_write32(rtwdev, 0x984, 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, 0xc88, 0x821403e3);
> + rtw_write32(rtwdev, 0xe88, 0x821403e3);
> + } else {
> + rtw_write32(rtwdev, 0xc88, 0x821403f7);
> + rtw_write32(rtwdev, 0xe88, 0x821403f7);
> + }
> + } else {
> + rtw_write32(rtwdev, 0xc88, 0x821403f1);
> + rtw_write32(rtwdev, 0xe88, 0x821403f1);
> + }
> +
> + if (rtwdev->hal.current_band_type == RTW_BAND_5G) {
> + rtw_write32(rtwdev, 0xc8c, 0x68163e96);
> + rtw_write32(rtwdev, 0xe8c, 0x68163e96);
> + } else {
> + rtw_write32(rtwdev, 0xc8c, 0x28163e96);
> + rtw_write32(rtwdev, 0xe8c, 0x28163e96);
> +
> + if (efuse->rfe_option == 3) {
> + if (efuse->ext_pa_2g)
> + rtw_write32(rtwdev, 0xc88, 0x821403e3);
> + else
> + rtw_write32(rtwdev, 0xc88, 0x821403f7);
> + }
> + }
> +
> + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> + rtw_write32(rtwdev, 0xc80, 0x18008c10);
> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
> + rtw_write32(rtwdev, 0xc84, 0x38008c10);
> + rtw_write32(rtwdev, 0xce8, 0x00000000);
> + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> + rtw_write32(rtwdev, 0xe80, 0x18008c10);
> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
> + rtw_write32(rtwdev, 0xe84, 0x38008c10);
> + rtw_write32(rtwdev, 0xee8, 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, 0x980, 0xfa000000);
> + rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> + mdelay(10);
> +
> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> + rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
> +
> + delay_count = 0;
> + while (1) {
prefer 'for'
> + if (!tx0_finish)
> + iqk0_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
> + if (!tx1_finish)
> + iqk1_ready = rtw_read32_mask(rtwdev, 0xd40, BIT(10));
> + if ((iqk0_ready && iqk1_ready) || delay_count > 20)
> + break;
> +
> + mdelay(1);
> + delay_count++;
> + }
> +
> + 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, 0xd00, BIT(12));
> + tx1_fail = rtw_read32_mask(rtwdev, 0xd40, BIT(12));
Can you collect undefined register addresses? I can try to lookup them in one go.
[...]
> +
> +#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] = {0};
> + u32 afe_backup[AFE_REG_NUM_8812A] = {0};
> + u32 rfa_backup[RF_REG_NUM_8812A] = {0};
> + u32 rfb_backup[RF_REG_NUM_8812A] = {0};
'= {}'
[...]
> +
> +static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
> +{}
Below looks regular.
static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
{
}
As well as rtw8821a_coex_cfg_gnt_debug() and rtw8821a_coex_cfg_wl_rx_gain()
[...]
> +static struct rtw_hw_reg rtw8821a_dig[] = {
const ?
> + [0] = { .addr = 0xc50, .mask = 0x7f },
> + [1] = { .addr = 0xe50, .mask = 0x7f },
> +};
> +
> +static struct rtw_page_table page_table_8821a[] = {
const ?
> + /* 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 struct rtw_page_table page_table_8812a[] = {
const ?
> + /* 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 struct rtw_rqpn rqpn_table_8821a[] = {
const ?
> + {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 struct rtw_prioq_addrs prioq_addrs_8821a = {
const?
> + .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 struct rtw_chip_ops rtw8821a_ops = {
> + .power_on = rtw8821a_power_on,
> + .power_off = rtw8821a_power_off,
> + .phy_set_param = NULL,
> + .read_efuse = rtw8821a_read_efuse,
> + .query_rx_desc = rtw8821a_query_rx_desc,
> + .set_channel = rtw8821a_set_channel,
> + .mac_init = NULL,
> + .read_rf = rtw8821a_phy_read_rf,
> + .write_rf = rtw_phy_write_rf_reg_sipi,
> + .set_antenna = NULL,
> + .set_tx_power_index = rtw8821a_set_tx_power_index,
> + .cfg_ldo25 = rtw8821a_cfg_ldo25,
> + .efuse_grant = rtw8821a_efuse_grant,
> + .false_alarm_statistics = rtw8821a_false_alarm_statistics,
> + .phy_calibration = rtw8821a_phy_calibration,
> + .cck_pd_set = rtw8821a_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,
> +};
> +
[...]
> +
> +const struct rtw_chip_info rtw8812a_hw_spec = {
Is it possible moving 8812a to individual file?
Since you have rtw8812au.c and rtw8821au.c.
> + .ops = &rtw8821a_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_8821a,
> + .prioq_addrs = &prioq_addrs_8821a,
> + .intf_table = &phy_para_table_8821a,
> + .dig = rtw8821a_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_8821a,
> + .bt_rssi_step = bt_rssi_step_8821a,
> + .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_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 = 0,
> + .afh_5g = NULL,
> +
> + .coex_info_hw_regs_num = 0,
> + .coex_info_hw_regs = NULL,
> +};
> +EXPORT_SYMBOL(rtw8812a_hw_spec);
> +
> +MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin");
> +MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");
> +
> +MODULE_AUTHOR("Realtek Corporation");
> +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a 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..7f1c2d2eb6d2
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
> @@ -0,0 +1,385 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019 Realtek Corporation
Year 2024
> + */
> +
> +#ifndef __RTW8821A_H__
> +#define __RTW8821A_H__
> +
> +#include <asm/byteorder.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
[...]
> +#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
> + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
> + (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
> + (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
BIT_SHIFT_SIFS_OFDM_CTX is defined in reg.h, so this header file should
include reg.h. Because every header file should be included independently.
> +
> +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
> + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
> +
> +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
> +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
> +#define WLAN_PRE_TXCNT_TIME_TH 0x1E4
> +
> +struct rtw8821a_phy_status_rpt {
> + /* DWORD 0 */
> + u8 gain_trsw[2]; /* path-A and path-B { TRSW, gain[6:0] } */
> + u8 chl_num_lsb; /* channel number[7:0] */
> +#ifdef __LITTLE_ENDIAN
> + u8 chl_num_msb:2; /* channel number[9:8] */
> + u8 sub_chnl:4; /* sub-channel location[3:0] */
> + u8 r_rfmod:2; /* RF mode[1:0] */
> +#else
> + u8 r_rfmod:2;
> + u8 sub_chnl:4;
> + u8 chl_num_msb:2;
> +#endif
Not prefer "#ifdef __LITTLE_ENDIAN" style, because we have never verified
big endian part. Prefer to define mask and access them via u8_get_bits() and
its friends.
> +
> + /* DWORD 1 */
> + u8 pwdb_all; /* CCK signal quality / OFDM pwdb all */
> + s8 cfosho[2]; /* CCK AGC report and CCK_BB_Power */
> + /* OFDM path-A and path-B short CFO */
> +#ifdef __LITTLE_ENDIAN
> + u8 resvd_0:6;
> + u8 bt_rf_ch_msb:2; /* 8812A: 2'b0 8814A: bt rf channel keep[7:6] */
Will you share this struct with 8814A? If not please remove comments related to 8814A.
> +#else
> + u8 bt_rf_ch_msb:2;
> + u8 resvd_0:6;
> +#endif
[...]
> +
> +#define REG_SYS_CTRL 0x000
> +#define BIT_FEN_EN BIT(26)
> +#define REG_APS_FSMCO 0x04
> +#define APS_FSMCO_MAC_ENABLE BIT(8)
> +#define APS_FSMCO_MAC_OFF BIT(9)
> +#define APS_FSMCO_HW_POWERDOWN BIT(15)
> +#define REG_ACLK_MON 0x3e
> +#define REG_RF_B_CTRL 0x76
> +#define REG_HIMR0 0xb0
> +#define REG_HISR0 0xb4
> +#define REG_HIMR1 0xb8
> +#define REG_HISR1 0xbc
[...]
Can't we move all of these registers (including what I delete) into reg.h?
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips
2024-08-15 6:10 ` Ping-Ke Shih
@ 2024-08-19 17:51 ` Bitterblue Smith
0 siblings, 0 replies; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-19 17:51 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 15/08/2024 09:10, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> RTL8821AU and RTL8812AU don't support this. They hit the "failed to read
>> hw feature report" error.
>>
>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>> ---
>> drivers/net/wireless/realtek/rtw88/main.c | 4 ++++
>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
>> 7 files changed, 10 insertions(+)
>>
>> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
>> index ff045dfdca4a..aeb21ac25e2e 100644
>> --- a/drivers/net/wireless/realtek/rtw88/main.c
>> +++ b/drivers/net/wireless/realtek/rtw88/main.c
>> @@ -1923,6 +1923,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
>> u8 bw;
>> int i;
>>
>> + if (!rtwdev->chip->hw_feature_report)
>> + goto print_hw_cap;
>
> Since chips don't support of hw_feature_report, printing hw capabilities seems
> useless. Just 'return'?
>
efuse->hw_cap is filled earlier in rtw8812a_read_usb_type(),
so printing here is not entirely useless. But maybe it is
cleaner to return here and print these things in
rtw8812a_read_usb_type().
>> +
>> id = rtw_read8(rtwdev, REG_C2HEVT);
>> if (id != C2H_HW_FEATURE_REPORT) {
>> rtw_err(rtwdev, "failed to read hw feature report\n");
>> @@ -1947,6 +1950,7 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
>> efuse->hw_cap.nss > rtwdev->hal.rf_path_num)
>> efuse->hw_cap.nss = rtwdev->hal.rf_path_num;
>>
>> +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,
>
> [...]
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-15 6:14 ` Ping-Ke Shih
@ 2024-08-19 17:52 ` Bitterblue Smith
2024-08-20 1:10 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-19 17:52 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 15/08/2024 09:14, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
>> Avoid the "invalid ra report c2h length" error.
>>
>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>> ---
>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
>> 7 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
>> index 782f3776e0a0..ac53e3e30af0 100644
>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
>>
>> rate = GET_RA_REPORT_RATE(ra_data->payload);
>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
>> - bw = GET_RA_REPORT_BW(ra_data->payload);
>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
>
> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
>
>> + bw = si->bw_mode;
>> + else
>> + bw = GET_RA_REPORT_BW(ra_data->payload);
>>
>
>
Would that make sense? I check for less than 7 because the size
has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL
2024-08-15 6:33 ` Ping-Ke Shih
@ 2024-08-19 17:53 ` Bitterblue Smith
2024-08-20 1:15 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-19 17:53 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 15/08/2024 09:33, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> RTL8821A doesn't have this. Trying to use it results in error messages,
>> so don't try if ltecoex_addr is NULL.
>
> In short term, it is fine to avoid these messages, but we need BT-coexistence
> for RTL8821A if we want better user experience with BT.
>
>>
>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>
>
> Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
>
>
I wasn't able to find this LTE stuff in the btc folder:
https://github.com/morrownr/8821au-20210708/tree/main/hal/btc
I did what I could to make the coexistence work, and it does.
I used my Bluetooth headphones for several days, listening to
music and watching videos. There is only a problem with the
wifi speeds with one router.
With ISP's HG6544C router:
Official driver: 3/5 Mbps.
rtw88: a bit more, but not steady at all. Not enough to watch
a 1080p Youtube video.
With my D-Link Eagle R32 router running Openwrt, on the same
channel:
Official driver: 6/10 Mbps.
rtw88: download starts around 30, climbs to 50 / upload is 10
Mbps. I can watch a 1080p Youtube video.
The music doesn't cut out during any speed tests.
I also tested transferring files to and from my phone. I don't
have other types of devices to test.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-19 17:52 ` Bitterblue Smith
@ 2024-08-20 1:10 ` Ping-Ke Shih
2024-08-20 21:44 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-20 1:10 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 15/08/2024 09:14, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
> >> Avoid the "invalid ra report c2h length" error.
> >>
> >> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> >> ---
> >> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
> >> drivers/net/wireless/realtek/rtw88/main.h | 1 +
> >> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
> >> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
> >> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
> >> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
> >> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
> >> 7 files changed, 12 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
> >> index 782f3776e0a0..ac53e3e30af0 100644
> >> --- a/drivers/net/wireless/realtek/rtw88/fw.c
> >> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
> >> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
> >>
> >> rate = GET_RA_REPORT_RATE(ra_data->payload);
> >> sgi = GET_RA_REPORT_SGI(ra_data->payload);
> >> - bw = GET_RA_REPORT_BW(ra_data->payload);
> >> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
> >
> > Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
> >
> >> + bw = si->bw_mode;
> >> + else
> >> + bw = GET_RA_REPORT_BW(ra_data->payload);
> >>
> >
> >
>
> Would that make sense? I check for less than 7 because the size
> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
Maybe explicitly specifying chips ID would be easier to understand:
if (chip == RTL8821A || chip == RTL8812A)
bw = si->bw_mode;
else
bw = GET_RA_REPORT_BW(ra_data->payload);
That's why I want "== 4". (but it seems implicitly not explicitly though.)
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL
2024-08-19 17:53 ` Bitterblue Smith
@ 2024-08-20 1:15 ` Ping-Ke Shih
0 siblings, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-20 1:15 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 15/08/2024 09:33, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >> RTL8821A doesn't have this. Trying to use it results in error messages,
> >> so don't try if ltecoex_addr is NULL.
> >
> > In short term, it is fine to avoid these messages, but we need BT-coexistence
> > for RTL8821A if we want better user experience with BT.
> >
> >>
> >> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> >
> >
> > Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
> >
> >
>
> I wasn't able to find this LTE stuff in the btc folder:
> https://github.com/morrownr/8821au-20210708/tree/main/hal/btc
>
> I did what I could to make the coexistence work, and it does.
> I used my Bluetooth headphones for several days, listening to
> music and watching videos. There is only a problem with the
> wifi speeds with one router.
>
> With ISP's HG6544C router:
> Official driver: 3/5 Mbps.
> rtw88: a bit more, but not steady at all. Not enough to watch
> a 1080p Youtube video.
>
> With my D-Link Eagle R32 router running Openwrt, on the same
> channel:
> Official driver: 6/10 Mbps.
> rtw88: download starts around 30, climbs to 50 / upload is 10
> Mbps. I can watch a 1080p Youtube video.
>
> The music doesn't cut out during any speed tests.
>
> I also tested transferring files to and from my phone. I don't
> have other types of devices to test.
Great! With these testing as evidence, we can approve your changes related to
BT-coexistence. Please add them to commit messages.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-20 1:10 ` Ping-Ke Shih
@ 2024-08-20 21:44 ` Bitterblue Smith
2024-08-21 0:31 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-20 21:44 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 20/08/2024 04:10, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> On 15/08/2024 09:14, Ping-Ke Shih wrote:
>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
>>>> Avoid the "invalid ra report c2h length" error.
>>>>
>>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>>>> ---
>>>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
>>>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
>>>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
>>>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
>>>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
>>>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
>>>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
>>>> 7 files changed, 12 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
>>>> index 782f3776e0a0..ac53e3e30af0 100644
>>>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
>>>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
>>>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
>>>>
>>>> rate = GET_RA_REPORT_RATE(ra_data->payload);
>>>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
>>>> - bw = GET_RA_REPORT_BW(ra_data->payload);
>>>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
>>>
>>> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
>>>
>>>> + bw = si->bw_mode;
>>>> + else
>>>> + bw = GET_RA_REPORT_BW(ra_data->payload);
>>>>
>>>
>>>
>>
>> Would that make sense? I check for less than 7 because the size
>> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
>
> As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
> expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
>
> Maybe explicitly specifying chips ID would be easier to understand:
> if (chip == RTL8821A || chip == RTL8812A)
> bw = si->bw_mode;
> else
> bw = GET_RA_REPORT_BW(ra_data->payload);
>
> That's why I want "== 4". (but it seems implicitly not explicitly though.)
>
I just checked, the RA report size of RTL8814AU is 6.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-20 21:44 ` Bitterblue Smith
@ 2024-08-21 0:31 ` Ping-Ke Shih
2024-08-21 11:13 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-21 0:31 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 20/08/2024 04:10, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >> On 15/08/2024 09:14, Ping-Ke Shih wrote:
> >>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
> >>>> Avoid the "invalid ra report c2h length" error.
> >>>>
> >>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> >>>> ---
> >>>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
> >>>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
> >>>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
> >>>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
> >>>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
> >>>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
> >>>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
> >>>> 7 files changed, 12 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
> >>>> index 782f3776e0a0..ac53e3e30af0 100644
> >>>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
> >>>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
> >>>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
> >>>>
> >>>> rate = GET_RA_REPORT_RATE(ra_data->payload);
> >>>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
> >>>> - bw = GET_RA_REPORT_BW(ra_data->payload);
> >>>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
> >>>
> >>> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
> >>>
> >>>> + bw = si->bw_mode;
> >>>> + else
> >>>> + bw = GET_RA_REPORT_BW(ra_data->payload);
> >>>>
> >>>
> >>>
> >>
> >> Would that make sense? I check for less than 7 because the size
> >> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
> >
> > As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
> > expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
> >
> > Maybe explicitly specifying chips ID would be easier to understand:
> > if (chip == RTL8821A || chip == RTL8812A)
> > bw = si->bw_mode;
> > else
> > bw = GET_RA_REPORT_BW(ra_data->payload);
> >
> > That's why I want "== 4". (but it seems implicitly not explicitly though.)
> >
>
> I just checked, the RA report size of RTL8814AU is 6.
Could you also check if the report format is compatible?
I mean definition of first 4 bytes are the same for all chips? and
definition of first 6 bytes are the same for RTL8814AU and current
exiting chips?
By the way, I think we should struct with w0, w1, ... fields instead.
struct rtw_ra_report {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
} __packed;
Then, we can be easier to avoid accessing out of range. GET_RA_REPORT_BW()
hides something, no help to read the code.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-21 0:31 ` Ping-Ke Shih
@ 2024-08-21 11:13 ` Bitterblue Smith
2024-08-22 0:33 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-21 11:13 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 21/08/2024 03:31, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> On 20/08/2024 04:10, Ping-Ke Shih wrote:
>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>> On 15/08/2024 09:14, Ping-Ke Shih wrote:
>>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
>>>>>> Avoid the "invalid ra report c2h length" error.
>>>>>>
>>>>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>>>>>> ---
>>>>>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
>>>>>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
>>>>>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
>>>>>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
>>>>>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
>>>>>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
>>>>>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
>>>>>> 7 files changed, 12 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
>>>>>> index 782f3776e0a0..ac53e3e30af0 100644
>>>>>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
>>>>>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
>>>>>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
>>>>>>
>>>>>> rate = GET_RA_REPORT_RATE(ra_data->payload);
>>>>>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
>>>>>> - bw = GET_RA_REPORT_BW(ra_data->payload);
>>>>>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
>>>>>
>>>>> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
>>>>>
>>>>>> + bw = si->bw_mode;
>>>>>> + else
>>>>>> + bw = GET_RA_REPORT_BW(ra_data->payload);
>>>>>>
>>>>>
>>>>>
>>>>
>>>> Would that make sense? I check for less than 7 because the size
>>>> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
>>>
>>> As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
>>> expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
>>>
>>> Maybe explicitly specifying chips ID would be easier to understand:
>>> if (chip == RTL8821A || chip == RTL8812A)
>>> bw = si->bw_mode;
>>> else
>>> bw = GET_RA_REPORT_BW(ra_data->payload);
>>>
>>> That's why I want "== 4". (but it seems implicitly not explicitly though.)
>>>
>>
>> I just checked, the RA report size of RTL8814AU is 6.
>
> Could you also check if the report format is compatible?
> I mean definition of first 4 bytes are the same for all chips? and
> definition of first 6 bytes are the same for RTL8814AU and current
> exiting chips?
>
> By the way, I think we should struct with w0, w1, ... fields instead.
> struct rtw_ra_report {
> __le32 w0;
> __le32 w1;
> __le32 w2;
> __le32 w3;
> __le32 w4;
> __le32 w5;
> __le32 w6;
> } __packed;
>
> Then, we can be easier to avoid accessing out of range. GET_RA_REPORT_BW()
> hides something, no help to read the code.
>
The report format looks compatible.
I'm not sure how a struct with __le32 members would help here.
I agree that the current macros hide things. We could access payload
directly. The variable names already make it clear what each byte is:
mac_id = ra_data->payload[1];
if (si->mac_id != mac_id)
return;
si->ra_report.txrate.flags = 0;
rate = u8_get_bits(ra_data->payload[0], GENMASK(6, 0));
sgi = u8_get_bits(ra_data->payload[0], BIT(7));
if (si->rtwdev->chip->c2h_ra_report_size >= 7)
bw = ra_data->payload[6];
else
bw = si->bw_mode;
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-21 11:13 ` Bitterblue Smith
@ 2024-08-22 0:33 ` Ping-Ke Shih
2024-08-22 6:58 ` Kalle Valo
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-08-22 0:33 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 21/08/2024 03:31, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >> On 20/08/2024 04:10, Ping-Ke Shih wrote:
> >>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>>> On 15/08/2024 09:14, Ping-Ke Shih wrote:
> >>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>>>>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
> >>>>>> Avoid the "invalid ra report c2h length" error.
> >>>>>>
> >>>>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> >>>>>> ---
> >>>>>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
> >>>>>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
> >>>>>> 7 files changed, 12 insertions(+), 2 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
> >>>>>> index 782f3776e0a0..ac53e3e30af0 100644
> >>>>>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
> >>>>>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
> >>>>>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
> >>>>>>
> >>>>>> rate = GET_RA_REPORT_RATE(ra_data->payload);
> >>>>>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
> >>>>>> - bw = GET_RA_REPORT_BW(ra_data->payload);
> >>>>>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
> >>>>>
> >>>>> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
> >>>>>
> >>>>>> + bw = si->bw_mode;
> >>>>>> + else
> >>>>>> + bw = GET_RA_REPORT_BW(ra_data->payload);
> >>>>>>
> >>>>>
> >>>>>
> >>>>
> >>>> Would that make sense? I check for less than 7 because the size
> >>>> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
> >>>
> >>> As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
> >>> expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
> >>>
> >>> Maybe explicitly specifying chips ID would be easier to understand:
> >>> if (chip == RTL8821A || chip == RTL8812A)
> >>> bw = si->bw_mode;
> >>> else
> >>> bw = GET_RA_REPORT_BW(ra_data->payload);
> >>>
> >>> That's why I want "== 4". (but it seems implicitly not explicitly though.)
> >>>
> >>
> >> I just checked, the RA report size of RTL8814AU is 6.
> >
> > Could you also check if the report format is compatible?
> > I mean definition of first 4 bytes are the same for all chips? and
> > definition of first 6 bytes are the same for RTL8814AU and current
> > exiting chips?
> >
> > By the way, I think we should struct with w0, w1, ... fields instead.
> > struct rtw_ra_report {
> > __le32 w0;
> > __le32 w1;
> > __le32 w2;
> > __le32 w3;
> > __le32 w4;
> > __le32 w5;
> > __le32 w6;
> > } __packed;
> >
> > Then, we can be easier to avoid accessing out of range. GET_RA_REPORT_BW()
> > hides something, no help to read the code.
> >
>
> The report format looks compatible.
>
> I'm not sure how a struct with __le32 members would help here.
> I agree that the current macros hide things. We could access payload
> directly. The variable names already make it clear what each byte is:
>
> mac_id = ra_data->payload[1];
> if (si->mac_id != mac_id)
> return;
>
> si->ra_report.txrate.flags = 0;
>
> rate = u8_get_bits(ra_data->payload[0], GENMASK(6, 0));
> sgi = u8_get_bits(ra_data->payload[0], BIT(7));
> if (si->rtwdev->chip->c2h_ra_report_size >= 7)
> bw = ra_data->payload[6];
> else
> bw = si->bw_mode;
Yes, this is also clear to me to avoid accessing out of range.
Another advantage of a struct is to explicitly tell us the total size of a
C2H event.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-22 0:33 ` Ping-Ke Shih
@ 2024-08-22 6:58 ` Kalle Valo
2024-08-22 14:04 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Kalle Valo @ 2024-08-22 6:58 UTC (permalink / raw)
To: Ping-Ke Shih; +Cc: Bitterblue Smith, linux-wireless@vger.kernel.org
Ping-Ke Shih <pkshih@realtek.com> writes:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>
>> On 21/08/2024 03:31, Ping-Ke Shih wrote:
>> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> >> On 20/08/2024 04:10, Ping-Ke Shih wrote:
>> >>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> >>>> On 15/08/2024 09:14, Ping-Ke Shih wrote:
>> >>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> >>>>>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
>> >>>>>> Avoid the "invalid ra report c2h length" error.
>> >>>>>>
>> >>>>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>> >>>>>> ---
>> >>>>>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
>> >>>>>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
>> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
>> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
>> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
>> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
>> >>>>>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
>> >>>>>> 7 files changed, 12 insertions(+), 2 deletions(-)
>> >>>>>>
>> >>>>>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
>> >>>>>> index 782f3776e0a0..ac53e3e30af0 100644
>> >>>>>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
>> >>>>>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
>> >>>>>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
>> >>>>>>
>> >>>>>> rate = GET_RA_REPORT_RATE(ra_data->payload);
>> >>>>>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
>> >>>>>> - bw = GET_RA_REPORT_BW(ra_data->payload);
>> >>>>>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
>> >>>>>
>> >>>>> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
>> >>>>>
>> >>>>>> + bw = si->bw_mode;
>> >>>>>> + else
>> >>>>>> + bw = GET_RA_REPORT_BW(ra_data->payload);
>> >>>>>>
>> >>>>>
>> >>>>>
>> >>>>
>> >>>> Would that make sense? I check for less than 7 because the size
>> >>>> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
>> >>>
>> >>> As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
>> >>> expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
>> >>>
>> >>> Maybe explicitly specifying chips ID would be easier to understand:
>> >>> if (chip == RTL8821A || chip == RTL8812A)
>> >>> bw = si->bw_mode;
>> >>> else
>> >>> bw = GET_RA_REPORT_BW(ra_data->payload);
>> >>>
>> >>> That's why I want "== 4". (but it seems implicitly not explicitly though.)
>> >>>
>> >>
>> >> I just checked, the RA report size of RTL8814AU is 6.
>> >
>> > Could you also check if the report format is compatible?
>> > I mean definition of first 4 bytes are the same for all chips? and
>> > definition of first 6 bytes are the same for RTL8814AU and current
>> > exiting chips?
>> >
>> > By the way, I think we should struct with w0, w1, ... fields instead.
>> > struct rtw_ra_report {
>> > __le32 w0;
>> > __le32 w1;
>> > __le32 w2;
>> > __le32 w3;
>> > __le32 w4;
>> > __le32 w5;
>> > __le32 w6;
>> > } __packed;
>> >
>> > Then, we can be easier to avoid accessing out of range. GET_RA_REPORT_BW()
>> > hides something, no help to read the code.
>> >
>>
>> The report format looks compatible.
>>
>> I'm not sure how a struct with __le32 members would help here.
>> I agree that the current macros hide things. We could access payload
>> directly. The variable names already make it clear what each byte is:
>>
>> mac_id = ra_data->payload[1];
>> if (si->mac_id != mac_id)
>> return;
>>
>> si->ra_report.txrate.flags = 0;
>>
>> rate = u8_get_bits(ra_data->payload[0], GENMASK(6, 0));
>> sgi = u8_get_bits(ra_data->payload[0], BIT(7));
>> if (si->rtwdev->chip->c2h_ra_report_size >= 7)
>> bw = ra_data->payload[6];
>> else
>> bw = si->bw_mode;
>
> Yes, this is also clear to me to avoid accessing out of range.
> Another advantage of a struct is to explicitly tell us the total size of a
> C2H event.
Yeah, please avoid that payload[6] stuff for parsing firmware commands
and events. It just makes the code harder to read and more fragile.
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes
2024-08-22 6:58 ` Kalle Valo
@ 2024-08-22 14:04 ` Bitterblue Smith
0 siblings, 0 replies; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-22 14:04 UTC (permalink / raw)
To: Kalle Valo, Ping-Ke Shih; +Cc: linux-wireless@vger.kernel.org
On 22/08/2024 09:58, Kalle Valo wrote:
> Ping-Ke Shih <pkshih@realtek.com> writes:
>
>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>
>>> On 21/08/2024 03:31, Ping-Ke Shih wrote:
>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>> On 20/08/2024 04:10, Ping-Ke Shih wrote:
>>>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>>>> On 15/08/2024 09:14, Ping-Ke Shih wrote:
>>>>>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>>>>>> The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes.
>>>>>>>>> Avoid the "invalid ra report c2h length" error.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>>>>>>>>> ---
>>>>>>>>> drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++--
>>>>>>>>> drivers/net/wireless/realtek/rtw88/main.h | 1 +
>>>>>>>>> drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
>>>>>>>>> drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
>>>>>>>>> drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
>>>>>>>>> drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
>>>>>>>>> drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
>>>>>>>>> 7 files changed, 12 insertions(+), 2 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
>>>>>>>>> index 782f3776e0a0..ac53e3e30af0 100644
>>>>>>>>> --- a/drivers/net/wireless/realtek/rtw88/fw.c
>>>>>>>>> +++ b/drivers/net/wireless/realtek/rtw88/fw.c
>>>>>>>>> @@ -157,7 +157,10 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
>>>>>>>>>
>>>>>>>>> rate = GET_RA_REPORT_RATE(ra_data->payload);
>>>>>>>>> sgi = GET_RA_REPORT_SGI(ra_data->payload);
>>>>>>>>> - bw = GET_RA_REPORT_BW(ra_data->payload);
>>>>>>>>> + if (si->rtwdev->chip->c2h_ra_report_size < 7)
>>>>>>>>
>>>>>>>> Explicitly specify '== 4' for the case of RTL8821AU and RTL8812AU.
>>>>>>>>
>>>>>>>>> + bw = si->bw_mode;
>>>>>>>>> + else
>>>>>>>>> + bw = GET_RA_REPORT_BW(ra_data->payload);
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> Would that make sense? I check for less than 7 because the size
>>>>>>> has to be at least 7 in order to access payload[6] (GET_RA_REPORT_BW).
>>>>>>
>>>>>> As you did "WARN(length < rtwdev->chip->c2h_ra_report_size)", I assume you
>>>>>> expect "< 7" cases is only for coming chips RTL8821AU and RTL8812AU.
>>>>>>
>>>>>> Maybe explicitly specifying chips ID would be easier to understand:
>>>>>> if (chip == RTL8821A || chip == RTL8812A)
>>>>>> bw = si->bw_mode;
>>>>>> else
>>>>>> bw = GET_RA_REPORT_BW(ra_data->payload);
>>>>>>
>>>>>> That's why I want "== 4". (but it seems implicitly not explicitly though.)
>>>>>>
>>>>>
>>>>> I just checked, the RA report size of RTL8814AU is 6.
>>>>
>>>> Could you also check if the report format is compatible?
>>>> I mean definition of first 4 bytes are the same for all chips? and
>>>> definition of first 6 bytes are the same for RTL8814AU and current
>>>> exiting chips?
>>>>
>>>> By the way, I think we should struct with w0, w1, ... fields instead.
>>>> struct rtw_ra_report {
>>>> __le32 w0;
>>>> __le32 w1;
>>>> __le32 w2;
>>>> __le32 w3;
>>>> __le32 w4;
>>>> __le32 w5;
>>>> __le32 w6;
>>>> } __packed;
>>>>
>>>> Then, we can be easier to avoid accessing out of range. GET_RA_REPORT_BW()
>>>> hides something, no help to read the code.
>>>>
>>>
>>> The report format looks compatible.
>>>
>>> I'm not sure how a struct with __le32 members would help here.
>>> I agree that the current macros hide things. We could access payload
>>> directly. The variable names already make it clear what each byte is:
>>>
>>> mac_id = ra_data->payload[1];
>>> if (si->mac_id != mac_id)
>>> return;
>>>
>>> si->ra_report.txrate.flags = 0;
>>>
>>> rate = u8_get_bits(ra_data->payload[0], GENMASK(6, 0));
>>> sgi = u8_get_bits(ra_data->payload[0], BIT(7));
>>> if (si->rtwdev->chip->c2h_ra_report_size >= 7)
>>> bw = ra_data->payload[6];
>>> else
>>> bw = si->bw_mode;
>>
>> Yes, this is also clear to me to avoid accessing out of range.
>> Another advantage of a struct is to explicitly tell us the total size of a
>> C2H event.
>
> Yeah, please avoid that payload[6] stuff for parsing firmware commands
> and events. It just makes the code harder to read and more fragile.
>
Okay, I will use a struct. This is similar to the solution
already accepted in rtl8xxxu:
struct rtw_c2h_ra_rpt {
u8 rate_sgi;
u8 mac_id;
u8 byte2;
u8 status;
u8 byte4;
u8 ra_ratio;
u8 bw;
u8 txcls_rate;
} __packed;
#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0)
#define RTW_C2H_RA_RPT_SGI BIT(7)
mac_id = ra_rpt->mac_id;
if (si->mac_id != mac_id)
return;
si->ra_report.txrate.flags = 0;
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;
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-08-16 6:06 ` Ping-Ke Shih
@ 2024-08-27 17:52 ` Bitterblue Smith
2024-09-10 2:30 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-08-27 17:52 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 16/08/2024 09:06, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> These contain all the logic for the RTL8821AU and RTL8812AU chips.
>>
>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>> ---
>> drivers/net/wireless/realtek/rtw88/rtw8821a.c | 4139 +++++++++++++++++
>> drivers/net/wireless/realtek/rtw88/rtw8821a.h | 385 ++
>> 2 files changed, 4524 insertions(+)
>> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c
>> create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h
>>
[...]
>> +static int rtw8821a_power_on(struct rtw_dev *rtwdev)
>> +{
>
> Will the coming RTL8814AU share this flow? If so, we can move this power on
> to main.c/mac.c as rtw_power_on_v1() or something else.
>
RTL8814AU will not use these power on/off functions. I'm hoping
it will work with the rtw_power_on/off functions. Right now I only
got as far as filling rtw8814a_table.c.
> If we decide moving power on flow into chip specific files, the duplicate code
> will become more and more. Please think about this.
>
>
>> + 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.
>> + */
>> + rtw8812au_hw_reset(rtwdev);
>> +
>> + ret = rtw8812au_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 = rtw8821a_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);
>> +
>> + rtw8821au_init_queue_reserved_page(rtwdev);
>> + rtw8821au_init_tx_buffer_boundary(rtwdev);
>> + rtw8821au_init_queue_priority(rtwdev);
>> +
>
> Seemingly above flow looks common. Can it share with other chips?
>
I don't know if any other chips can use this.
> [...]
>
>> +}
>> +
>> +static u32 rtw8821a_phy_read_rf(struct rtw_dev *rtwdev,
>> + enum rtw_rf_path rf_path, u32 addr, u32 mask)
>> +{
>
> read/write RF functions are also common for chips. Can it share with coming RTL8814A?
> Move this to phy.c as v1?
>
No, RTL8814A will use rtw_phy_read_rf(), like RTL8822B.
>> + static const u32 pi_addr[2] = { 0xc00, 0xe00 };
>> + static const u32 read_addr[2][2] = {
>> + { REG_SI_READ_A, REG_SI_READ_B },
>> + { REG_PI_READ_A, REG_PI_READ_B }
>> + };
>
> [...]
>
>> +
>> +static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
>> + struct rtw_rx_pkt_stat *pkt_stat)
>> +{
>> + struct rtw_dm_info *dm_info = &rtwdev->dm_info;
>> + struct rtw8821a_phy_status_rpt *phy_sts;
>> + u8 lna_idx, vga_idx, cck_agc_rpt;
>> + s8 rx_pwr_db, power_a, power_b;
>> + const s8 min_rx_power = -120;
>> + u8 rssi, val, i;
>> +
>> + phy_sts = (struct rtw8821a_phy_status_rpt *)phy_status;
>> +
>> + if (pkt_stat->rate <= DESC_RATE11M) {
>> + cck_agc_rpt = phy_sts->cfosho[0];
>> + lna_idx = (cck_agc_rpt & 0xE0) >> 5;
>> + vga_idx = cck_agc_rpt & 0x1F;
>
> If we remove "#ifdef __LITTLE_ENDIAN" from rtw8821a_phy_status_rpt and define
> bit mask there, additionally define these bit masks and then use u8_get_bits().
>
> By the way, shouldn't the field of 'cfosho[2]' be 'u8' instead of 's8'?
>
Those bytes mean different things for CCK and for OFDM. I suppose
they need to be s8 for "short CFO" (OFDM) but u8 for "CCK AGC report".
They are s8 in the official driver.
>> +
>> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
>> + rx_pwr_db = rtw8821a_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
>> + else
>> + rx_pwr_db = rtw8812a_cck_rx_pwr(rtwdev, 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;
>> +
>> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A &&
>> + !rtwdev->hal.cck_high_power) {
>> + 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;
>> + }
>> + } else { /* OFDM rate */
>> + for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) {
>> + val = phy_sts->gain_trsw[i];
>> + pkt_stat->rx_power[i] = (val & 0x7F) - 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);
>> + }
>> +}
>> +
>> +static void rtw8821a_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
>> + struct rtw_rx_pkt_stat *pkt_stat,
>> + struct ieee80211_rx_status *rx_status)
>> +{
>> + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
>> + struct ieee80211_hdr *hdr;
>> + u8 *phy_status = NULL;
>> +
>> + memset(pkt_stat, 0, sizeof(*pkt_stat));
>> +
>> + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
>> + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
>> + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
>> + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
>> + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
>> + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
>> + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
>> + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
>> + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
>> + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
>> + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
>> + pkt_stat->ppdu_cnt = 0;
>> + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
>> + pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
>
> More and more chips use these macros. Please add a patch using struct to
> access these fields. More, query_rx_desc() are very similar across chips,
> please move them to mac.c or phy.c as a common function.
>
Why not rx.c?
>> +
>> + /* drv_info_sz is in unit of 8-bytes */
>> + pkt_stat->drv_info_sz *= 8;
>> +
>> + /* c2h cmd pkt's rx/phy status is not interested */
>> + if (pkt_stat->is_c2h)
>> + return;
>> +
>> + hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
>> + pkt_stat->drv_info_sz);
>> + if (pkt_stat->phy_status) {
>> + phy_status = rx_desc + desc_sz + pkt_stat->shift;
>> + rtw8821a_query_phy_status(rtwdev, phy_status, pkt_stat);
>> + }
>> +
>> + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
>> +}
>> +
[...]
>> +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 <= 2; k++) {
>
> '< 3' would be more intuitive, because 'k' is index of array.
>
>> + switch (k) {
>> + case 0:
>> + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
>> + rtw_write32(rtwdev, 0xc80, 0x18008c38);
>> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
>> + rtw_write32(rtwdev, 0xc84, 0x38008c38);
>> + rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0);
>> + break;
>> + case 1:
>> + rtw_write32_mask(rtwdev, 0xc80, BIT(28), 0x0);
>> + rtw_write32_mask(rtwdev, 0xc84, BIT(28), 0x0);
>> + rtw_write32_mask(rtwdev, 0xce8, 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, 0xc80, 0x18008c20);
>> + /* RX_Tone_idx[9:0], RxK_Mask[29] */
>> + rtw_write32(rtwdev, 0xc84, 0x38008c20);
>> + rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x1);
>> + rtw_write32_mask(rtwdev, 0xce8, 0x3fff0000,
>> + tx_dt[cal] & 0x00003fff);
>> + break;
>> + }
>> +
>> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
>> + cal_retry = 0;
>> + while (1) {
>
> Can we replace 'while()' by 'for (cal_retry = 0; cal_retry < 10; cal_retry++)'?
>
I think so.
>> + /* one shot */
>> + rtw_write32(rtwdev, 0x980, 0xfa000000);
>> + rtw_write32(rtwdev, 0x980, 0xf8000000);
>> +
>> + mdelay(10);
>> +
>> + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
>> +
>> + delay_count = 0;
>> + while (1) {
>
[...]
>> + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
>> + /* ============TXIQK Check============== */
>> + tx0_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12));
>> + tx1_fail = rtw_read32_mask(rtwdev, 0xd40, BIT(12));
>
> Can you collect undefined register addresses? I can try to lookup them in one go.
>
Here are the addresses I could find and a few bits/bit masks:
0x765
0x90c
0x978
31, 0x03ff8000, 0x000007ff
0x97c
31
0x980
0x984
0xa0a
0xc00
0xf
0xc5c
GENMASK(26, 24)
0xce8
31, 0x3fff0000
0xd00
10, 11, 12, 0x07ff0000
0xd40
10, 11, 12
0xe00
0xe5c
GENMASK(26, 24)
0xe80
0xe84
0xe88
0xe8c
0xe90
7
0xe94
0
0xec4
18, 29
0xec8
29
0xecc
0xed4
0xee8
0xf008
3, 4
0xf050
And some RF registers: 0x8, 0x58, 0x65, 0x8f
[...]
>> +
>> +const struct rtw_chip_info rtw8812a_hw_spec = {
>
> Is it possible moving 8812a to individual file?
> Since you have rtw8812au.c and rtw8821au.c.
>
I think it is possible. But most of the code is common to both chips.
Only the IQ calibration could be moved.
Another possibility is to move rtw8812au.c into rtw8821au.c and have
only one module handle both chips.
>> + .ops = &rtw8821a_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_8821a,
>> + .prioq_addrs = &prioq_addrs_8821a,
>> + .intf_table = &phy_para_table_8821a,
>> + .dig = rtw8821a_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_8821a,
>> + .bt_rssi_step = bt_rssi_step_8821a,
>> + .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_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 = 0,
>> + .afh_5g = NULL,
>> +
>> + .coex_info_hw_regs_num = 0,
>> + .coex_info_hw_regs = NULL,
>> +};
>> +EXPORT_SYMBOL(rtw8812a_hw_spec);
>> +
>> +MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin");
>> +MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");
>> +
>> +MODULE_AUTHOR("Realtek Corporation");
>> +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a 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..7f1c2d2eb6d2
>> --- /dev/null
>> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
>> @@ -0,0 +1,385 @@
>> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
>> +/* Copyright(c) 2018-2019 Realtek Corporation
>
> Year 2024
>
>> + */
>> +
>> +#ifndef __RTW8821A_H__
>> +#define __RTW8821A_H__
>> +
>> +#include <asm/byteorder.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
>
> [...]
>
>> +#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
>> + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
>> + (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
>> + (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
>
> BIT_SHIFT_SIFS_OFDM_CTX is defined in reg.h, so this header file should
> include reg.h. Because every header file should be included independently.
>
>> +
>> +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
>> + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
>> +
>> +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
>> +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
>> +#define WLAN_PRE_TXCNT_TIME_TH 0x1E4
>> +
>> +struct rtw8821a_phy_status_rpt {
>> + /* DWORD 0 */
>> + u8 gain_trsw[2]; /* path-A and path-B { TRSW, gain[6:0] } */
>> + u8 chl_num_lsb; /* channel number[7:0] */
>> +#ifdef __LITTLE_ENDIAN
>> + u8 chl_num_msb:2; /* channel number[9:8] */
>> + u8 sub_chnl:4; /* sub-channel location[3:0] */
>> + u8 r_rfmod:2; /* RF mode[1:0] */
>> +#else
>> + u8 r_rfmod:2;
>> + u8 sub_chnl:4;
>> + u8 chl_num_msb:2;
>> +#endif
>
> Not prefer "#ifdef __LITTLE_ENDIAN" style, because we have never verified
> big endian part. Prefer to define mask and access them via u8_get_bits() and
> its friends.
>
None of the members inside #ifdef __LITLLE_ENDIAN are used
in this driver. Do I still have to define all the masks?
>
>> +
>> + /* DWORD 1 */
>> + u8 pwdb_all; /* CCK signal quality / OFDM pwdb all */
>> + s8 cfosho[2]; /* CCK AGC report and CCK_BB_Power */
>> + /* OFDM path-A and path-B short CFO */
>> +#ifdef __LITTLE_ENDIAN
>> + u8 resvd_0:6;
>> + u8 bt_rf_ch_msb:2; /* 8812A: 2'b0 8814A: bt rf channel keep[7:6] */
>
> Will you share this struct with 8814A? If not please remove comments related to 8814A.
>
Yes, it uses the same struct.
>> +#else
>> + u8 bt_rf_ch_msb:2;
>> + u8 resvd_0:6;
>> +#endif
>
> [...]
>
>
>> +
>> +#define REG_SYS_CTRL 0x000
>> +#define BIT_FEN_EN BIT(26)
>> +#define REG_APS_FSMCO 0x04
>> +#define APS_FSMCO_MAC_ENABLE BIT(8)
>> +#define APS_FSMCO_MAC_OFF BIT(9)
>> +#define APS_FSMCO_HW_POWERDOWN BIT(15)
>> +#define REG_ACLK_MON 0x3e
>> +#define REG_RF_B_CTRL 0x76
>> +#define REG_HIMR0 0xb0
>> +#define REG_HISR0 0xb4
>> +#define REG_HIMR1 0xb8
>> +#define REG_HISR1 0xbc
>
> [...]
>
> Can't we move all of these registers (including what I delete) into reg.h?
>
I think so.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-08-27 17:52 ` Bitterblue Smith
@ 2024-09-10 2:30 ` Ping-Ke Shih
2024-09-12 15:59 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-09-10 2:30 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 16/08/2024 09:06, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >> + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
> >> + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
> >> + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
> >> + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
> >> + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
> >> + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
> >> + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
> >> + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
> >> + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
> >> + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
> >> + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
> >> + pkt_stat->ppdu_cnt = 0;
> >> + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
> >> + pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
> >
> > More and more chips use these macros. Please add a patch using struct to
> > access these fields. More, query_rx_desc() are very similar across chips,
> > please move them to mac.c or phy.c as a common function.
> >
>
> Why not rx.c?
Also fine to me.
> > Can you collect undefined register addresses? I can try to lookup them in one go.
> >
>
> Here are the addresses I could find and a few bits/bit masks:
>
> 0x765
#define REG_GNT_BT 0x765
#define BIT_PTA_SW_CTL GENMASK(4, 3)
> 0x90c
#define REG_DAC_RSTB 0x90c
> 0x978
> 31, 0x03ff8000, 0x000007ff
> 0x97c
> 31
> 0x980
> 0x984
#define REG_IQK_COM00 0x978
#define REG_IQK_COM32 0x97c
#define REG_IQK_COM64 0x980
#define REG_IQK_COM96 0x984
> 0xa0a
#define REG_CCK_PD_TH 0xa0a
> 0xc00
> 0xf
> 0xe00
#define REG_3WIRE_SWA 0xc00
#define REG_3WIRE_SWB 0xe00
(0xc00 page for path A, 0xe00 page for path B)
> 0xc5c
> 0xe5c
> GENMASK(26, 24)
#define REG_CK_MONHA 0xc5c
#define REG_CK_MONHB 0xe5c
> 0xce8
> 31, 0x3fff0000
> 0xee8
#define REG_INTPO_SETA 0xce8
#define REG_INTPO_SETB 0xee8
> 0xd00
> 10, 11, 12, 0x07ff0000
#define REG_IQKA_END 0xd00
> 0xd40
> 10, 11, 12
#define REG_IQKB_END 0xd40
> GENMASK(26, 24)
> 0xe80
#define REG_TXTONEB 0xe80
> 0xe84
#define REG_RXTONEB 0xe84
> 0xe88
#define REG_TXPITMB 0xe88
> 0xe8c
#define REG_RXPITMB 0xe8c
> 0xe90
#define REG_PREDISTB 0xe90
> 7
> 0xe94
#define REG_INIDLYB 0xe94
> 0
> 0xec4
> 18, 29
#define REG_BPBDB 0xec4
> 0xec8
> 29
#define REG_PHYTXONB 0xec8
> 0xecc
#define REG_IQKYB 0xecc
> 0xed4
#define REG_IQKXB 0xed4
> 0xf008
> 3, 4
> 0xf050
I can't find these two, but just follow comments above.
#define REG_USB_MOD 0xf008
#define REG_USB3_RXITV 0xf050
>
> And some RF registers: 0x8, 0x58, 0x65, 0x8f
>
#define RF_DTXLOK 0x08 (already existing)
#define RF_TXMOD 0x58
#define RF_TXA_PREPAD 0x65
#define RF_RXBB2 0x8f
> [...]
>
> >> +
> >> +const struct rtw_chip_info rtw8812a_hw_spec = {
> >
> > Is it possible moving 8812a to individual file?
> > Since you have rtw8812au.c and rtw8821au.c.
> >
>
> I think it is possible. But most of the code is common to both chips.
> Only the IQ calibration could be moved.
Yep, depend on how much IQK code echo chip has.
>
> Another possibility is to move rtw8812au.c into rtw8821au.c and have
> only one module handle both chips.
Prefer two modules as was. That is clear to people we have two chips.
> >> +
> >> +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
> >> + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
> >> +
> >> +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
> >> +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
> >> +#define WLAN_PRE_TXCNT_TIME_TH 0x1E4
> >> +
> >> +struct rtw8821a_phy_status_rpt {
> >> + /* DWORD 0 */
> >> + u8 gain_trsw[2]; /* path-A and path-B { TRSW, gain[6:0] } */
> >> + u8 chl_num_lsb; /* channel number[7:0] */
> >> +#ifdef __LITTLE_ENDIAN
> >> + u8 chl_num_msb:2; /* channel number[9:8] */
> >> + u8 sub_chnl:4; /* sub-channel location[3:0] */
> >> + u8 r_rfmod:2; /* RF mode[1:0] */
> >> +#else
> >> + u8 r_rfmod:2;
> >> + u8 sub_chnl:4;
> >> + u8 chl_num_msb:2;
> >> +#endif
> >
> > Not prefer "#ifdef __LITTLE_ENDIAN" style, because we have never verified
> > big endian part. Prefer to define mask and access them via u8_get_bits() and
> > its friends.
> >
>
> None of the members inside #ifdef __LITLLE_ENDIAN are used
> in this driver. Do I still have to define all the masks?
I prefer to define all masks, because the names have been there. Adding a name
in the future may be painful.
>
> >
> >> +
> >> + /* DWORD 1 */
> >> + u8 pwdb_all; /* CCK signal quality / OFDM pwdb all */
> >> + s8 cfosho[2]; /* CCK AGC report and CCK_BB_Power */
> >> + /* OFDM path-A and path-B short CFO */
> >> +#ifdef __LITTLE_ENDIAN
> >> + u8 resvd_0:6;
> >> + u8 bt_rf_ch_msb:2; /* 8812A: 2'b0 8814A: bt rf channel keep[7:6] */
> >
> > Will you share this struct with 8814A? If not please remove comments related to 8814A.
> >
>
> Yes, it uses the same struct.
But struct name is rtw8821a_phy_status_rpt that prefix is rtw8821a.
> >> +
> >> +#define REG_SYS_CTRL 0x000
> >> +#define BIT_FEN_EN BIT(26)
> >> +#define REG_APS_FSMCO 0x04
> >> +#define APS_FSMCO_MAC_ENABLE BIT(8)
> >> +#define APS_FSMCO_MAC_OFF BIT(9)
> >> +#define APS_FSMCO_HW_POWERDOWN BIT(15)
> >> +#define REG_ACLK_MON 0x3e
> >> +#define REG_RF_B_CTRL 0x76
> >> +#define REG_HIMR0 0xb0
> >> +#define REG_HISR0 0xb4
> >> +#define REG_HIMR1 0xb8
> >> +#define REG_HISR1 0xbc
> >
> > [...]
> >
> > Can't we move all of these registers (including what I delete) into reg.h?
> >
>
> I think so.
I remember we were afraid that definitions of registers for each are different,
so put them in chip specific header file. But now I feel most registers can be
shared, and easy to read code because we need spending extra time to disambiguate
duplicate definitions.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-10 2:30 ` Ping-Ke Shih
@ 2024-09-12 15:59 ` Bitterblue Smith
2024-09-13 1:50 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-09-12 15:59 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 10/09/2024 05:30, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> On 16/08/2024 09:06, Ping-Ke Shih wrote:
>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>> + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
>>>> + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
>>>> + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
>>>> + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
>>>> + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
>>>> + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
>>>> + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
>>>> + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
>>>> + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
>>>> + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
>>>> + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
>>>> + pkt_stat->ppdu_cnt = 0;
>>>> + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
>>>> + pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
>>>
>>> More and more chips use these macros. Please add a patch using struct to
>>> access these fields. More, query_rx_desc() are very similar across chips,
>>> please move them to mac.c or phy.c as a common function.
>>>
>>
>> Why not rx.c?
>
> Also fine to me.
>
>>> Can you collect undefined register addresses? I can try to lookup them in one go.
>>>
>>
>> Here are the addresses I could find and a few bits/bit masks:
>>
>> 0x765
>
> #define REG_GNT_BT 0x765
> #define BIT_PTA_SW_CTL GENMASK(4, 3)
>
>> 0x90c
>
> #define REG_DAC_RSTB 0x90c
>
>> 0x978
>> 31, 0x03ff8000, 0x000007ff
>> 0x97c
>> 31
>> 0x980
>> 0x984
>
> #define REG_IQK_COM00 0x978
> #define REG_IQK_COM32 0x97c
> #define REG_IQK_COM64 0x980
> #define REG_IQK_COM96 0x984
>
>> 0xa0a
>
> #define REG_CCK_PD_TH 0xa0a
>
>> 0xc00
>> 0xf
>> 0xe00
>
> #define REG_3WIRE_SWA 0xc00
> #define REG_3WIRE_SWB 0xe00
>
> (0xc00 page for path A, 0xe00 page for path B)
>
Previously, you called 0xe00 REG_HSSI_WRITE_B. Are both names correct?
(I'm not sure why I put 0xc00 and 0xe00 on the list if you already gave
them a name.)
>> 0xc5c
>> 0xe5c
>> GENMASK(26, 24)
>
> #define REG_CK_MONHA 0xc5c
> #define REG_CK_MONHB 0xe5c
>
>> 0xce8
>> 31, 0x3fff0000
>> 0xee8
>
> #define REG_INTPO_SETA 0xce8
> #define REG_INTPO_SETB 0xee8
>
>> 0xd00
>> 10, 11, 12, 0x07ff0000
>
> #define REG_IQKA_END 0xd00
>
>> 0xd40
>> 10, 11, 12
>
> #define REG_IQKB_END 0xd40
>
>> GENMASK(26, 24)
>> 0xe80
>
> #define REG_TXTONEB 0xe80
>
>> 0xe84
>
> #define REG_RXTONEB 0xe84
>
>> 0xe88
>
> #define REG_TXPITMB 0xe88
>
>> 0xe8c
>
> #define REG_RXPITMB 0xe8c
>
>> 0xe90
>
> #define REG_PREDISTB 0xe90
>
I put 0xe90 on the list by mistake. We already have a name for it
in the official driver:
./include/Hal8812PhyReg.h:66:#define rB_LSSIWrite_Jaguar 0xe90 /* RF write addr */
I translated that as REG_LSSI_WRITE_B. Is REG_PREDISTB also a valid
name? Do we need both names?
>> 7
>> 0xe94
>
> #define REG_INIDLYB 0xe94
>
>> 0
>> 0xec4
>> 18, 29
>
>
> #define REG_BPBDB 0xec4
>
>> 0xec8
>> 29
>
> #define REG_PHYTXONB 0xec8
>
Some of these names are very different from their counterparts
from page C. In your previous email you said:
> I think we can reuse existing definitions:
>
> rtw8723x.h:#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
> rtw8703b.h:#define REG_OFDM0_A_TX_AFE 0x0c84
> rtw8723x.h:#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88
>
> #define REG_TSSI_TRK_SW 0xc8c
>
> rtw8821a.h:#define REG_TXAGCIDX 0xc94
Can we reuse these definitions?
>> 0xecc
>
> #define REG_IQKYB 0xecc
>
>> 0xed4
>
> #define REG_IQKXB 0xed4
>
>> 0xf008
>> 3, 4
>> 0xf050
>
> I can't find these two, but just follow comments above.
>
> #define REG_USB_MOD 0xf008
> #define REG_USB3_RXITV 0xf050
>
>
>>
>> And some RF registers: 0x8, 0x58, 0x65, 0x8f
>>
>
> #define RF_DTXLOK 0x08 (already existing)
> #define RF_TXMOD 0x58
> #define RF_TXA_PREPAD 0x65
> #define RF_RXBB2 0x8f
>
>
>> [...]
>>
>>>> +
>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
>>>
>>> Is it possible moving 8812a to individual file?
>>> Since you have rtw8812au.c and rtw8821au.c.
>>>
>>
>> I think it is possible. But most of the code is common to both chips.
>> Only the IQ calibration could be moved.
>
> Yep, depend on how much IQK code echo chip has.
>
The IQ calibration for RTL8812AU is about 700 lines.
>>
>> Another possibility is to move rtw8812au.c into rtw8821au.c and have
>> only one module handle both chips.
>
> Prefer two modules as was. That is clear to people we have two chips.
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-12 15:59 ` Bitterblue Smith
@ 2024-09-13 1:50 ` Ping-Ke Shih
2024-09-21 22:47 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-09-13 1:50 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
> >
> > #define REG_3WIRE_SWA 0xc00
> > #define REG_3WIRE_SWB 0xe00
> >
> > (0xc00 page for path A, 0xe00 page for path B)
> >
>
> Previously, you called 0xe00 REG_HSSI_WRITE_B. Are both names correct?
> (I'm not sure why I put 0xc00 and 0xe00 on the list if you already gave
> them a name.)
In fact, there is no _formal_ names for PHY registers, so I gave names by
abbreviation name from RTL code. Previously I may reference to vendor
drivers instead. Just choose one you like.
> >> 0xe90
> >
> > #define REG_PREDISTB 0xe90
> >
>
> I put 0xe90 on the list by mistake. We already have a name for it
> in the official driver:
>
> ./include/Hal8812PhyReg.h:66:#define rB_LSSIWrite_Jaguar 0xe90 /* RF write addr */
>
> I translated that as REG_LSSI_WRITE_B. Is REG_PREDISTB also a valid
> name? Do we need both names?
For the use case of 0xe90 in rtw8812a_iqk_tx_fill():
rtw_write32_mask(rtwdev, 0xc90, BIT(7), 0x1);
"RF write addr" seems not reasonable. I suggest to define both for this case.
> Some of these names are very different from their counterparts
> from page C. In your previous email you said:
>
> > I think we can reuse existing definitions:
> >
> > rtw8723x.h:#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
> > rtw8703b.h:#define REG_OFDM0_A_TX_AFE 0x0c84
> > rtw8723x.h:#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88
> >
> > #define REG_TSSI_TRK_SW 0xc8c
> >
> > rtw8821a.h:#define REG_TXAGCIDX 0xc94
>
> Can we reuse these definitions?
Yes. You can reuse existing first. For non-existing definition, use the names
I gave in this thread.
Basically we can have two ways to have names. One is from vendor drivers, and
the other is from abbreviation name of RTL code, which bit name instead of
whole register name is given. Also I'm not very familiar with the functionality,
so I did just paste reasonable names for undefined magic numbers.
> >>>> +
> >>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
> >>>
> >>> Is it possible moving 8812a to individual file?
> >>> Since you have rtw8812au.c and rtw8821au.c.
> >>>
> >>
> >> I think it is possible. But most of the code is common to both chips.
> >> Only the IQ calibration could be moved.
> >
> > Yep, depend on how much IQK code echo chip has.
> >
>
> The IQ calibration for RTL8812AU is about 700 lines.
rtw8812au -----> (a) rtw8812a
|
v
(b) rtw8821a_common (hard to give a name)
^
|
rtw8821au -----> (c) rtw8821a
Put all common code to (b). IQK code in (a) or (c).
I feel you have thought above picture already. What are problems we will encounter?
Many export symbols? If so, how about below?
rtw8812au -----> (1) rtw8812a
+---------+
+-> (2) rtw8821a_common (hard to give a name)
+---------+
rtw8821au -----> (3) rtw8821a
Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
respectively, and export IQK entry only. Does it work?
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-13 1:50 ` Ping-Ke Shih
@ 2024-09-21 22:47 ` Bitterblue Smith
2024-09-23 5:47 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-09-21 22:47 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 13/09/2024 04:50, Ping-Ke Shih wrote:
>>>
>>> #define REG_3WIRE_SWA 0xc00
>>> #define REG_3WIRE_SWB 0xe00
>>>
>>> (0xc00 page for path A, 0xe00 page for path B)
>>>
>>
>> Previously, you called 0xe00 REG_HSSI_WRITE_B. Are both names correct?
>> (I'm not sure why I put 0xc00 and 0xe00 on the list if you already gave
>> them a name.)
>
> In fact, there is no _formal_ names for PHY registers, so I gave names by
> abbreviation name from RTL code. Previously I may reference to vendor
> drivers instead. Just choose one you like.
>
>>>> 0xe90
>>>
>>> #define REG_PREDISTB 0xe90
>>>
>>
>> I put 0xe90 on the list by mistake. We already have a name for it
>> in the official driver:
>>
>> ./include/Hal8812PhyReg.h:66:#define rB_LSSIWrite_Jaguar 0xe90 /* RF write addr */
>>
>> I translated that as REG_LSSI_WRITE_B. Is REG_PREDISTB also a valid
>> name? Do we need both names?
>
> For the use case of 0xe90 in rtw8812a_iqk_tx_fill():
>
> rtw_write32_mask(rtwdev, 0xc90, BIT(7), 0x1);
>
> "RF write addr" seems not reasonable. I suggest to define both for this case.
>
>
>> Some of these names are very different from their counterparts
>> from page C. In your previous email you said:
>>
>>> I think we can reuse existing definitions:
>>>
>>> rtw8723x.h:#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
>>> rtw8703b.h:#define REG_OFDM0_A_TX_AFE 0x0c84
>>> rtw8723x.h:#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88
>>>
>>> #define REG_TSSI_TRK_SW 0xc8c
>>>
>>> rtw8821a.h:#define REG_TXAGCIDX 0xc94
>>
>> Can we reuse these definitions?
>
> Yes. You can reuse existing first. For non-existing definition, use the names
> I gave in this thread.
>
> Basically we can have two ways to have names. One is from vendor drivers, and
> the other is from abbreviation name of RTL code, which bit name instead of
> whole register name is given. Also I'm not very familiar with the functionality,
> so I did just paste reasonable names for undefined magic numbers.
>
I see. Thank you for the explanations.
>>>>>> +
>>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
>>>>>
>>>>> Is it possible moving 8812a to individual file?
>>>>> Since you have rtw8812au.c and rtw8821au.c.
>>>>>
>>>>
>>>> I think it is possible. But most of the code is common to both chips.
>>>> Only the IQ calibration could be moved.
>>>
>>> Yep, depend on how much IQK code echo chip has.
>>>
>>
>> The IQ calibration for RTL8812AU is about 700 lines.
>
> rtw8812au -----> (a) rtw8812a
> |
> v
> (b) rtw8821a_common (hard to give a name)
> ^
> |
> rtw8821au -----> (c) rtw8821a
>
> Put all common code to (b). IQK code in (a) or (c).
>
> I feel you have thought above picture already. What are problems we will encounter?
> Many export symbols? If so, how about below?
>
> rtw8812au -----> (1) rtw8812a
> +---------+
> +-> (2) rtw8821a_common (hard to give a name)
> +---------+
> rtw8821au -----> (3) rtw8821a
>
> Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
> respectively, and export IQK entry only. Does it work?
>
>
For the name of the common module, I was thinking rtw88_88xxa.ko.
I wonder, what is the goal? To put the code in separate kernel
modules, or just separate files?
I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
three files compile into a single module, rtw88_88xxa.ko.
If each file compiles into a module of its own, we have circular
dependencies: rtw8821a_hw_spec -> common code -> IQK code.
If *_hw_spec go in the common module, it still depends on both of
the other two modules, so what use is it?
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-21 22:47 ` Bitterblue Smith
@ 2024-09-23 5:47 ` Ping-Ke Shih
2024-09-23 5:58 ` Ping-Ke Shih
2024-09-24 21:19 ` Bitterblue Smith
0 siblings, 2 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-09-23 5:47 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>>>>> +
> >>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
> >>>>>
> >>>>> Is it possible moving 8812a to individual file?
> >>>>> Since you have rtw8812au.c and rtw8821au.c.
> >>>>>
> >>>>
> >>>> I think it is possible. But most of the code is common to both chips.
> >>>> Only the IQ calibration could be moved.
> >>>
> >>> Yep, depend on how much IQK code echo chip has.
> >>>
> >>
> >> The IQ calibration for RTL8812AU is about 700 lines.
> >
> > rtw8812au -----> (a) rtw8812a
> > |
> > v
> > (b) rtw8821a_common (hard to give a name)
> > ^
> > |
> > rtw8821au -----> (c) rtw8821a
> >
> > Put all common code to (b). IQK code in (a) or (c).
> >
> > I feel you have thought above picture already. What are problems we will encounter?
> > Many export symbols? If so, how about below?
> >
> > rtw8812au -----> (1) rtw8812a
> > +---------+
> > +-> (2) rtw8821a_common (hard to give a name)
> > +---------+
> > rtw8821au -----> (3) rtw8821a
> >
> > Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
> > respectively, and export IQK entry only. Does it work?
> >
> >
> For the name of the common module, I was thinking rtw88_88xxa.ko.
>
> I wonder, what is the goal? To put the code in separate kernel
> modules, or just separate files?
I would like to reduce runtime memory. As I asked, how many IQK code are different
from them? If you have separated and compiled them, can you share size by the
output of 'size' command?
>
> I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
> rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
> rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
> three files compile into a single module, rtw88_88xxa.ko.
>
> If each file compiles into a module of its own, we have circular
> dependencies: rtw8821a_hw_spec -> common code -> IQK code.
> If *_hw_spec go in the common module, it still depends on both of
> the other two modules, so what use is it?
If we have dependency of common code -> IQK code, we can't save runtime
memory, because common code reference to both IQK code. So I felt
dependency of IQK code would be rtw8812au --> IQK code as above second
diagram.
But if the work is complicated and save not few runtime memory, we can
use simple design as current did.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-23 5:47 ` Ping-Ke Shih
@ 2024-09-23 5:58 ` Ping-Ke Shih
2024-09-24 21:19 ` Bitterblue Smith
1 sibling, 0 replies; 64+ messages in thread
From: Ping-Ke Shih @ 2024-09-23 5:58 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Ping-Ke Shih <pkshih@realtek.com> wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> > >>>>>> +
> > >>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
> > >>>>>
> > >>>>> Is it possible moving 8812a to individual file?
> > >>>>> Since you have rtw8812au.c and rtw8821au.c.
> > >>>>>
> > >>>>
> > >>>> I think it is possible. But most of the code is common to both chips.
> > >>>> Only the IQ calibration could be moved.
> > >>>
> > >>> Yep, depend on how much IQK code echo chip has.
> > >>>
> > >>
> > >> The IQ calibration for RTL8812AU is about 700 lines.
> > >
> > > rtw8812au -----> (a) rtw8812a
> > > |
> > > v
> > > (b) rtw8821a_common (hard to give a name)
> > > ^
> > > |
> > > rtw8821au -----> (c) rtw8821a
> > >
> > > Put all common code to (b). IQK code in (a) or (c).
> > >
> > > I feel you have thought above picture already. What are problems we will encounter?
> > > Many export symbols? If so, how about below?
> > >
> > > rtw8812au -----> (1) rtw8812a
> > > +---------+
> > > +-> (2) rtw8821a_common (hard to give a name)
> > > +---------+
> > > rtw8821au -----> (3) rtw8821a
> > >
> > > Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
> > > respectively, and export IQK entry only. Does it work?
> > >
> > >
> > For the name of the common module, I was thinking rtw88_88xxa.ko.
> >
> > I wonder, what is the goal? To put the code in separate kernel
> > modules, or just separate files?
>
> I would like to reduce runtime memory. As I asked, how many IQK code are different
> from them? If you have separated and compiled them, can you share size by the
> output of 'size' command?
>
> >
> > I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
> > rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
> > rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
> > three files compile into a single module, rtw88_88xxa.ko.
> >
> > If each file compiles into a module of its own, we have circular
> > dependencies: rtw8821a_hw_spec -> common code -> IQK code.
> > If *_hw_spec go in the common module, it still depends on both of
> > the other two modules, so what use is it?
>
> If we have dependency of common code -> IQK code, we can't save runtime
> memory, because common code reference to both IQK code. So I felt
> dependency of IQK code would be rtw8812au --> IQK code as above second
> diagram.
>
> But if the work is complicated and save few runtime memory, we can
> use simple design as current did.
>
Sorry. Correct typo. "... save few runtime memory ..." (remove 'not')
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-23 5:47 ` Ping-Ke Shih
2024-09-23 5:58 ` Ping-Ke Shih
@ 2024-09-24 21:19 ` Bitterblue Smith
2024-09-25 1:25 ` Ping-Ke Shih
1 sibling, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-09-24 21:19 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 23/09/2024 08:47, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>>>>> +
>>>>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
>>>>>>>
>>>>>>> Is it possible moving 8812a to individual file?
>>>>>>> Since you have rtw8812au.c and rtw8821au.c.
>>>>>>>
>>>>>>
>>>>>> I think it is possible. But most of the code is common to both chips.
>>>>>> Only the IQ calibration could be moved.
>>>>>
>>>>> Yep, depend on how much IQK code echo chip has.
>>>>>
>>>>
>>>> The IQ calibration for RTL8812AU is about 700 lines.
>>>
>>> rtw8812au -----> (a) rtw8812a
>>> |
>>> v
>>> (b) rtw8821a_common (hard to give a name)
>>> ^
>>> |
>>> rtw8821au -----> (c) rtw8821a
>>>
>>> Put all common code to (b). IQK code in (a) or (c).
>>>
>>> I feel you have thought above picture already. What are problems we will encounter?
>>> Many export symbols? If so, how about below?
>>>
>>> rtw8812au -----> (1) rtw8812a
>>> +---------+
>>> +-> (2) rtw8821a_common (hard to give a name)
>>> +---------+
>>> rtw8821au -----> (3) rtw8821a
>>>
>>> Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
>>> respectively, and export IQK entry only. Does it work?
>>>
>>>
>> For the name of the common module, I was thinking rtw88_88xxa.ko.
>>
>> I wonder, what is the goal? To put the code in separate kernel
>> modules, or just separate files?
>
> I would like to reduce runtime memory. As I asked, how many IQK code are different
> from them? If you have separated and compiled them, can you share size by the
> output of 'size' command?
>
I separated the IQK code into two files (still just one module).
size says:
text data bss dec hex filename
7192 32 0 7224 1c38 rtw8821a-iqk.o
12319 40 0 12359 3047 rtw8812a-iqk.o
This is x86_64.
>>
>> I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
>> rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
>> rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
>> three files compile into a single module, rtw88_88xxa.ko.
>>
>> If each file compiles into a module of its own, we have circular
>> dependencies: rtw8821a_hw_spec -> common code -> IQK code.
>> If *_hw_spec go in the common module, it still depends on both of
>> the other two modules, so what use is it?
>
> If we have dependency of common code -> IQK code, we can't save runtime
> memory, because common code reference to both IQK code. So I felt
> dependency of IQK code would be rtw8812au --> IQK code as above second
> diagram.
>
> But if the work is complicated and save not few runtime memory, we can
> use simple design as current did.
>
>
The IQK code can be separated into different modules if I duplicate
rtw8821a_ops and rtw8821a_pwr_track, and rtw8821a_phy_pwrtrack takes
a pointer to the IQK function. Then your first diagram above can work.
The tables also take up a bit of space:
text data bss dec hex filename
16832 0 0 16832 41c0 rtw8821a_table.o
21552 0 0 21552 5430 rtw8812a_table.o
I don't know how many kilobytes is enough to make it worth
creating two more modules.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-24 21:19 ` Bitterblue Smith
@ 2024-09-25 1:25 ` Ping-Ke Shih
2024-09-25 11:28 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-09-25 1:25 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 23/09/2024 08:47, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>>>>>>> +
> >>>>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
> >>>>>>>
> >>>>>>> Is it possible moving 8812a to individual file?
> >>>>>>> Since you have rtw8812au.c and rtw8821au.c.
> >>>>>>>
> >>>>>>
> >>>>>> I think it is possible. But most of the code is common to both chips.
> >>>>>> Only the IQ calibration could be moved.
> >>>>>
> >>>>> Yep, depend on how much IQK code echo chip has.
> >>>>>
> >>>>
> >>>> The IQ calibration for RTL8812AU is about 700 lines.
> >>>
> >>> rtw8812au -----> (a) rtw8812a
> >>> |
> >>> v
> >>> (b) rtw8821a_common (hard to give a name)
> >>> ^
> >>> |
> >>> rtw8821au -----> (c) rtw8821a
> >>>
> >>> Put all common code to (b). IQK code in (a) or (c).
> >>>
> >>> I feel you have thought above picture already. What are problems we will encounter?
> >>> Many export symbols? If so, how about below?
> >>>
> >>> rtw8812au -----> (1) rtw8812a
> >>> +---------+
> >>> +-> (2) rtw8821a_common (hard to give a name)
> >>> +---------+
> >>> rtw8821au -----> (3) rtw8821a
> >>>
> >>> Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
> >>> respectively, and export IQK entry only. Does it work?
> >>>
> >>>
> >> For the name of the common module, I was thinking rtw88_88xxa.ko.
> >>
> >> I wonder, what is the goal? To put the code in separate kernel
> >> modules, or just separate files?
> >
> > I would like to reduce runtime memory. As I asked, how many IQK code are different
> > from them? If you have separated and compiled them, can you share size by the
> > output of 'size' command?
> >
>
> I separated the IQK code into two files (still just one module).
> size says:
>
> text data bss dec hex filename
> 7192 32 0 7224 1c38 rtw8821a-iqk.o
> 12319 40 0 12359 3047 rtw8812a-iqk.o
>
> This is x86_64.
>
> >>
> >> I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
> >> rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
> >> rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
> >> three files compile into a single module, rtw88_88xxa.ko.
> >>
> >> If each file compiles into a module of its own, we have circular
> >> dependencies: rtw8821a_hw_spec -> common code -> IQK code.
> >> If *_hw_spec go in the common module, it still depends on both of
> >> the other two modules, so what use is it?
> >
> > If we have dependency of common code -> IQK code, we can't save runtime
> > memory, because common code reference to both IQK code. So I felt
> > dependency of IQK code would be rtw8812au --> IQK code as above second
> > diagram.
> >
> > But if the work is complicated and save not few runtime memory, we can
> > use simple design as current did.
> >
> >
>
> The IQK code can be separated into different modules if I duplicate
> rtw8821a_ops and rtw8821a_pwr_track, and rtw8821a_phy_pwrtrack takes
> a pointer to the IQK function. Then your first diagram above can work.
Not sure the "duplicate" you meant. If it only a struct, that would be fine.
Not prefer duplicate of tables.
>
> The tables also take up a bit of space:
>
> text data bss dec hex filename
> 16832 0 0 16832 41c0 rtw8821a_table.o
> 21552 0 0 21552 5430 rtw8812a_table.o
Good point.
>
> I don't know how many kilobytes is enough to make it worth
> creating two more modules.
I think we can list all *.o related to rtw8821a/8812a, and check the
percentage to make decisions. I mean if it occupies 50%, I will prefer
to have separated module. But I don't have an exact number now.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-25 1:25 ` Ping-Ke Shih
@ 2024-09-25 11:28 ` Bitterblue Smith
2024-09-26 2:27 ` Ping-Ke Shih
0 siblings, 1 reply; 64+ messages in thread
From: Bitterblue Smith @ 2024-09-25 11:28 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 25/09/2024 04:25, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> On 23/09/2024 08:47, Ping-Ke Shih wrote:
>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>>>>>>> +
>>>>>>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
>>>>>>>>>
>>>>>>>>> Is it possible moving 8812a to individual file?
>>>>>>>>> Since you have rtw8812au.c and rtw8821au.c.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I think it is possible. But most of the code is common to both chips.
>>>>>>>> Only the IQ calibration could be moved.
>>>>>>>
>>>>>>> Yep, depend on how much IQK code echo chip has.
>>>>>>>
>>>>>>
>>>>>> The IQ calibration for RTL8812AU is about 700 lines.
>>>>>
>>>>> rtw8812au -----> (a) rtw8812a
>>>>> |
>>>>> v
>>>>> (b) rtw8821a_common (hard to give a name)
>>>>> ^
>>>>> |
>>>>> rtw8821au -----> (c) rtw8821a
>>>>>
>>>>> Put all common code to (b). IQK code in (a) or (c).
>>>>>
>>>>> I feel you have thought above picture already. What are problems we will encounter?
>>>>> Many export symbols? If so, how about below?
>>>>>
>>>>> rtw8812au -----> (1) rtw8812a
>>>>> +---------+
>>>>> +-> (2) rtw8821a_common (hard to give a name)
>>>>> +---------+
>>>>> rtw8821au -----> (3) rtw8821a
>>>>>
>>>>> Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
>>>>> respectively, and export IQK entry only. Does it work?
>>>>>
>>>>>
>>>> For the name of the common module, I was thinking rtw88_88xxa.ko.
>>>>
>>>> I wonder, what is the goal? To put the code in separate kernel
>>>> modules, or just separate files?
>>>
>>> I would like to reduce runtime memory. As I asked, how many IQK code are different
>>> from them? If you have separated and compiled them, can you share size by the
>>> output of 'size' command?
>>>
>>
>> I separated the IQK code into two files (still just one module).
>> size says:
>>
>> text data bss dec hex filename
>> 7192 32 0 7224 1c38 rtw8821a-iqk.o
>> 12319 40 0 12359 3047 rtw8812a-iqk.o
>>
>> This is x86_64.
>>
>>>>
>>>> I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
>>>> rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
>>>> rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
>>>> three files compile into a single module, rtw88_88xxa.ko.
>>>>
>>>> If each file compiles into a module of its own, we have circular
>>>> dependencies: rtw8821a_hw_spec -> common code -> IQK code.
>>>> If *_hw_spec go in the common module, it still depends on both of
>>>> the other two modules, so what use is it?
>>>
>>> If we have dependency of common code -> IQK code, we can't save runtime
>>> memory, because common code reference to both IQK code. So I felt
>>> dependency of IQK code would be rtw8812au --> IQK code as above second
>>> diagram.
>>>
>>> But if the work is complicated and save not few runtime memory, we can
>>> use simple design as current did.
>>>
>>>
>>
>> The IQK code can be separated into different modules if I duplicate
>> rtw8821a_ops and rtw8821a_pwr_track, and rtw8821a_phy_pwrtrack takes
>> a pointer to the IQK function. Then your first diagram above can work.
>
> Not sure the "duplicate" you meant. If it only a struct, that would be fine.
> Not prefer duplicate of tables.
>
Yes, it's a struct rtw_chip_ops.
>>
>> The tables also take up a bit of space:
>>
>> text data bss dec hex filename
>> 16832 0 0 16832 41c0 rtw8821a_table.o
>> 21552 0 0 21552 5430 rtw8812a_table.o
>
> Good point.
>
>>
>> I don't know how many kilobytes is enough to make it worth
>> creating two more modules.
>
> I think we can list all *.o related to rtw8821a/8812a, and check the
> percentage to make decisions. I mean if it occupies 50%, I will prefer
> to have separated module. But I don't have an exact number now.
>
text data bss dec hex filename
12319 40 0 12359 3047 rtw8812a-iqk.o
21552 0 0 21552 5430 rtw8812a_table.o
7192 32 0 7224 1c38 rtw8821a-iqk.o
16832 0 0 16832 41c0 rtw8821a_table.o
29445 429 0 29874 74b2 rtw8821a.o
=========
87340 total. So it's about 38% for 8812a and 27% for 8821a.
Maybe a bit more in the final version.
^ permalink raw reply [flat|nested] 64+ messages in thread
* RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-25 11:28 ` Bitterblue Smith
@ 2024-09-26 2:27 ` Ping-Ke Shih
2024-09-26 16:41 ` Bitterblue Smith
0 siblings, 1 reply; 64+ messages in thread
From: Ping-Ke Shih @ 2024-09-26 2:27 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 25/09/2024 04:25, Ping-Ke Shih wrote:
> > Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >> On 23/09/2024 08:47, Ping-Ke Shih wrote:
> >>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> >>>>>>>>>> +
> >>>>>>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
> >>>>>>>>>
> >>>>>>>>> Is it possible moving 8812a to individual file?
> >>>>>>>>> Since you have rtw8812au.c and rtw8821au.c.
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> I think it is possible. But most of the code is common to both chips.
> >>>>>>>> Only the IQ calibration could be moved.
> >>>>>>>
> >>>>>>> Yep, depend on how much IQK code echo chip has.
> >>>>>>>
> >>>>>>
> >>>>>> The IQ calibration for RTL8812AU is about 700 lines.
> >>>>>
> >>>>> rtw8812au -----> (a) rtw8812a
> >>>>> |
> >>>>> v
> >>>>> (b) rtw8821a_common (hard to give a name)
> >>>>> ^
> >>>>> |
> >>>>> rtw8821au -----> (c) rtw8821a
> >>>>>
> >>>>> Put all common code to (b). IQK code in (a) or (c).
> >>>>>
> >>>>> I feel you have thought above picture already. What are problems we will encounter?
> >>>>> Many export symbols? If so, how about below?
> >>>>>
> >>>>> rtw8812au -----> (1) rtw8812a
> >>>>> +---------+
> >>>>> +-> (2) rtw8821a_common (hard to give a name)
> >>>>> +---------+
> >>>>> rtw8821au -----> (3) rtw8821a
> >>>>>
> >>>>> Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
> >>>>> respectively, and export IQK entry only. Does it work?
> >>>>>
> >>>>>
> >>>> For the name of the common module, I was thinking rtw88_88xxa.ko.
> >>>>
> >>>> I wonder, what is the goal? To put the code in separate kernel
> >>>> modules, or just separate files?
> >>>
> >>> I would like to reduce runtime memory. As I asked, how many IQK code are different
> >>> from them? If you have separated and compiled them, can you share size by the
> >>> output of 'size' command?
> >>>
> >>
> >> I separated the IQK code into two files (still just one module).
> >> size says:
> >>
> >> text data bss dec hex filename
> >> 7192 32 0 7224 1c38 rtw8821a-iqk.o
> >> 12319 40 0 12359 3047 rtw8812a-iqk.o
> >>
> >> This is x86_64.
> >>
> >>>>
> >>>> I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
> >>>> rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
> >>>> rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
> >>>> three files compile into a single module, rtw88_88xxa.ko.
> >>>>
> >>>> If each file compiles into a module of its own, we have circular
> >>>> dependencies: rtw8821a_hw_spec -> common code -> IQK code.
> >>>> If *_hw_spec go in the common module, it still depends on both of
> >>>> the other two modules, so what use is it?
> >>>
> >>> If we have dependency of common code -> IQK code, we can't save runtime
> >>> memory, because common code reference to both IQK code. So I felt
> >>> dependency of IQK code would be rtw8812au --> IQK code as above second
> >>> diagram.
> >>>
> >>> But if the work is complicated and save not few runtime memory, we can
> >>> use simple design as current did.
> >>>
> >>>
> >>
> >> The IQK code can be separated into different modules if I duplicate
> >> rtw8821a_ops and rtw8821a_pwr_track, and rtw8821a_phy_pwrtrack takes
> >> a pointer to the IQK function. Then your first diagram above can work.
> >
> > Not sure the "duplicate" you meant. If it only a struct, that would be fine.
> > Not prefer duplicate of tables.
> >
>
> Yes, it's a struct rtw_chip_ops.
>
> >>
> >> The tables also take up a bit of space:
> >>
> >> text data bss dec hex filename
> >> 16832 0 0 16832 41c0 rtw8821a_table.o
> >> 21552 0 0 21552 5430 rtw8812a_table.o
> >
> > Good point.
> >
> >>
> >> I don't know how many kilobytes is enough to make it worth
> >> creating two more modules.
> >
> > I think we can list all *.o related to rtw8821a/8812a, and check the
> > percentage to make decisions. I mean if it occupies 50%, I will prefer
> > to have separated module. But I don't have an exact number now.
> >
>
> text data bss dec hex filename
> 12319 40 0 12359 3047 rtw8812a-iqk.o
> 21552 0 0 21552 5430 rtw8812a_table.o
> 7192 32 0 7224 1c38 rtw8821a-iqk.o
> 16832 0 0 16832 41c0 rtw8821a_table.o
> 29445 429 0 29874 74b2 rtw8821a.o
> =========
> 87340 total. So it's about 38% for 8812a and 27% for 8821a.
> Maybe a bit more in the final version.
chip separated(a) single one(b) increase rate(c)
----- ------------ ------------- ----------------
8812a 63,785 87,841 38%
8821a 53,930 87,841 63%
* increase rate (c) = (b - a) / a
Since increasing rate of 8821a is 63%, I feel separated case would be better.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}
2024-09-26 2:27 ` Ping-Ke Shih
@ 2024-09-26 16:41 ` Bitterblue Smith
0 siblings, 0 replies; 64+ messages in thread
From: Bitterblue Smith @ 2024-09-26 16:41 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 26/09/2024 05:27, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> On 25/09/2024 04:25, Ping-Ke Shih wrote:
>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>> On 23/09/2024 08:47, Ping-Ke Shih wrote:
>>>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>>>>>>>>>> +
>>>>>>>>>>>> +const struct rtw_chip_info rtw8812a_hw_spec = {
>>>>>>>>>>>
>>>>>>>>>>> Is it possible moving 8812a to individual file?
>>>>>>>>>>> Since you have rtw8812au.c and rtw8821au.c.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I think it is possible. But most of the code is common to both chips.
>>>>>>>>>> Only the IQ calibration could be moved.
>>>>>>>>>
>>>>>>>>> Yep, depend on how much IQK code echo chip has.
>>>>>>>>>
>>>>>>>>
>>>>>>>> The IQ calibration for RTL8812AU is about 700 lines.
>>>>>>>
>>>>>>> rtw8812au -----> (a) rtw8812a
>>>>>>> |
>>>>>>> v
>>>>>>> (b) rtw8821a_common (hard to give a name)
>>>>>>> ^
>>>>>>> |
>>>>>>> rtw8821au -----> (c) rtw8821a
>>>>>>>
>>>>>>> Put all common code to (b). IQK code in (a) or (c).
>>>>>>>
>>>>>>> I feel you have thought above picture already. What are problems we will encounter?
>>>>>>> Many export symbols? If so, how about below?
>>>>>>>
>>>>>>> rtw8812au -----> (1) rtw8812a
>>>>>>> +---------+
>>>>>>> +-> (2) rtw8821a_common (hard to give a name)
>>>>>>> +---------+
>>>>>>> rtw8821au -----> (3) rtw8821a
>>>>>>>
>>>>>>> Put rtw8812a_hw_spec and rtw8821a_hw_spec in (2). Only IQK code in (1) and (3)
>>>>>>> respectively, and export IQK entry only. Does it work?
>>>>>>>
>>>>>>>
>>>>>> For the name of the common module, I was thinking rtw88_88xxa.ko.
>>>>>>
>>>>>> I wonder, what is the goal? To put the code in separate kernel
>>>>>> modules, or just separate files?
>>>>>
>>>>> I would like to reduce runtime memory. As I asked, how many IQK code are different
>>>>> from them? If you have separated and compiled them, can you share size by the
>>>>> output of 'size' command?
>>>>>
>>>>
>>>> I separated the IQK code into two files (still just one module).
>>>> size says:
>>>>
>>>> text data bss dec hex filename
>>>> 7192 32 0 7224 1c38 rtw8821a-iqk.o
>>>> 12319 40 0 12359 3047 rtw8812a-iqk.o
>>>>
>>>> This is x86_64.
>>>>
>>>>>>
>>>>>> I think we can have rtw88xxa.c (common code), rtw8821a.c (IQK code,
>>>>>> rtw8821a_hw_spec, bluetooth stuff), and rtw8812a.c (IQK code,
>>>>>> rtw8812a_hw_spec, some efuse stuff, channel switching)... if these
>>>>>> three files compile into a single module, rtw88_88xxa.ko.
>>>>>>
>>>>>> If each file compiles into a module of its own, we have circular
>>>>>> dependencies: rtw8821a_hw_spec -> common code -> IQK code.
>>>>>> If *_hw_spec go in the common module, it still depends on both of
>>>>>> the other two modules, so what use is it?
>>>>>
>>>>> If we have dependency of common code -> IQK code, we can't save runtime
>>>>> memory, because common code reference to both IQK code. So I felt
>>>>> dependency of IQK code would be rtw8812au --> IQK code as above second
>>>>> diagram.
>>>>>
>>>>> But if the work is complicated and save not few runtime memory, we can
>>>>> use simple design as current did.
>>>>>
>>>>>
>>>>
>>>> The IQK code can be separated into different modules if I duplicate
>>>> rtw8821a_ops and rtw8821a_pwr_track, and rtw8821a_phy_pwrtrack takes
>>>> a pointer to the IQK function. Then your first diagram above can work.
>>>
>>> Not sure the "duplicate" you meant. If it only a struct, that would be fine.
>>> Not prefer duplicate of tables.
>>>
>>
>> Yes, it's a struct rtw_chip_ops.
>>
>>>>
>>>> The tables also take up a bit of space:
>>>>
>>>> text data bss dec hex filename
>>>> 16832 0 0 16832 41c0 rtw8821a_table.o
>>>> 21552 0 0 21552 5430 rtw8812a_table.o
>>>
>>> Good point.
>>>
>>>>
>>>> I don't know how many kilobytes is enough to make it worth
>>>> creating two more modules.
>>>
>>> I think we can list all *.o related to rtw8821a/8812a, and check the
>>> percentage to make decisions. I mean if it occupies 50%, I will prefer
>>> to have separated module. But I don't have an exact number now.
>>>
>>
>> text data bss dec hex filename
>> 12319 40 0 12359 3047 rtw8812a-iqk.o
>> 21552 0 0 21552 5430 rtw8812a_table.o
>> 7192 32 0 7224 1c38 rtw8821a-iqk.o
>> 16832 0 0 16832 41c0 rtw8821a_table.o
>> 29445 429 0 29874 74b2 rtw8821a.o
>> =========
>> 87340 total. So it's about 38% for 8812a and 27% for 8821a.
>> Maybe a bit more in the final version.
>
> chip separated(a) single one(b) increase rate(c)
> ----- ------------ ------------- ----------------
> 8812a 63,785 87,841 38%
> 8821a 53,930 87,841 63%
>
> * increase rate (c) = (b - a) / a
>
> Since increasing rate of 8821a is 63%, I feel separated case would be better.
>
>
All right.
^ permalink raw reply [flat|nested] 64+ messages in thread
end of thread, other threads:[~2024-09-26 16:41 UTC | newest]
Thread overview: 64+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-11 20:53 [PATCH 00/20] wifi: rtw88: Add support for RTL8821AU and RTL8812AU Bitterblue Smith
2024-08-11 20:54 ` [PATCH 01/20] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU Bitterblue Smith
2024-08-15 6:34 ` Ping-Ke Shih
2024-08-11 20:54 ` [PATCH 02/20] wifi: rtw88: Dump the HW features only for some chips Bitterblue Smith
2024-08-15 6:10 ` Ping-Ke Shih
2024-08-19 17:51 ` Bitterblue Smith
2024-08-11 20:55 ` [PATCH 03/20] wifi: rtw88: Allow different C2H RA report sizes Bitterblue Smith
2024-08-15 6:14 ` Ping-Ke Shih
2024-08-19 17:52 ` Bitterblue Smith
2024-08-20 1:10 ` Ping-Ke Shih
2024-08-20 21:44 ` Bitterblue Smith
2024-08-21 0:31 ` Ping-Ke Shih
2024-08-21 11:13 ` Bitterblue Smith
2024-08-22 0:33 ` Ping-Ke Shih
2024-08-22 6:58 ` Kalle Valo
2024-08-22 14:04 ` Bitterblue Smith
2024-08-11 20:55 ` [PATCH 04/20] wifi: rtw88: Extend the init table parsing for RTL8812AU Bitterblue Smith
2024-08-15 6:27 ` Ping-Ke Shih
2024-08-11 20:57 ` [PATCH 05/20] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL Bitterblue Smith
2024-08-15 6:33 ` Ping-Ke Shih
2024-08-19 17:53 ` Bitterblue Smith
2024-08-20 1:15 ` Ping-Ke Shih
2024-08-11 20:57 ` [PATCH 06/20] wifi: rtw88: Let each driver control the power on/off process Bitterblue Smith
2024-08-11 20:59 ` [PATCH 07/20] wifi: rtw88: Enable data rate fallback for older chips Bitterblue Smith
2024-08-15 6:46 ` Ping-Ke Shih
2024-08-11 21:00 ` [PATCH 08/20] wifi: rtw88: Make txagc_remnant_ofdm an array Bitterblue Smith
2024-08-15 6:50 ` Ping-Ke Shih
2024-08-11 21:00 ` [PATCH 09/20] wifi: rtw88: Support TX page sizes bigger than 128 Bitterblue Smith
2024-08-15 6:52 ` Ping-Ke Shih
2024-08-11 21:01 ` [PATCH 10/20] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def Bitterblue Smith
2024-08-15 7:00 ` Ping-Ke Shih
2024-08-11 21:02 ` [PATCH 11/20] wifi: rtw88: usb: Set pkt_info.ls for the reserved page Bitterblue Smith
2024-08-15 7:07 ` Ping-Ke Shih
2024-08-11 21:02 ` [PATCH 12/20] wifi: rtw88: Detect beacon loss with chips other than 8822c Bitterblue Smith
2024-08-15 7:16 ` Ping-Ke Shih
2024-08-11 21:03 ` [PATCH 13/20] wifi: rtw88: coex: Support chips without a scoreboard Bitterblue Smith
2024-08-15 7:19 ` Ping-Ke Shih
2024-08-11 21:04 ` [PATCH 14/20] wifi: rtw88: 8821a: Regularly ask for BT info updates Bitterblue Smith
2024-08-15 7:26 ` Ping-Ke Shih
2024-08-11 21:05 ` [PATCH 15/20] wifi: rtw88: 8812a: Mitigate beacon loss Bitterblue Smith
2024-08-15 7:31 ` Ping-Ke Shih
2024-08-11 21:06 ` [PATCH 16/20] wifi: rtw88: Add rtw8812a_table.{c,h} Bitterblue Smith
2024-08-15 7:53 ` Ping-Ke Shih
2024-08-16 1:19 ` Ping-Ke Shih
2024-08-11 21:06 ` [PATCH 17/20] wifi: rtw88: Add rtw8821a_table.{c,h} Bitterblue Smith
2024-08-15 7:55 ` Ping-Ke Shih
2024-08-11 21:07 ` [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h} Bitterblue Smith
2024-08-16 6:06 ` Ping-Ke Shih
2024-08-27 17:52 ` Bitterblue Smith
2024-09-10 2:30 ` Ping-Ke Shih
2024-09-12 15:59 ` Bitterblue Smith
2024-09-13 1:50 ` Ping-Ke Shih
2024-09-21 22:47 ` Bitterblue Smith
2024-09-23 5:47 ` Ping-Ke Shih
2024-09-23 5:58 ` Ping-Ke Shih
2024-09-24 21:19 ` Bitterblue Smith
2024-09-25 1:25 ` Ping-Ke Shih
2024-09-25 11:28 ` Bitterblue Smith
2024-09-26 2:27 ` Ping-Ke Shih
2024-09-26 16:41 ` Bitterblue Smith
2024-08-11 21:08 ` [PATCH 19/20] wifi: rtw88: Add rtw8821au.c and rtw8812au.c Bitterblue Smith
2024-08-15 7:58 ` Ping-Ke Shih
2024-08-11 21:11 ` [PATCH 20/20] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers Bitterblue Smith
2024-08-15 8:01 ` Ping-Ke Shih
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).