2024-03-11 10:38:23

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B

This patch set adds a driver for RTL8723CS, which is used in the
Pinephone and a few other devices. It is a combined wifi/bluetooth
device, the wifi part is called RTL8703B. There is already a mainline
driver for the bluetooth part. RTL8703B is similar to the RTL8723D
chip already supported by rtw88. I've been using the out-of-tree
rtl8723cs driver as reference.

Station and monitor mode work well enough for daily use on my
Pinephone, I have not tested other modes yet. WOW firmware is
declared, but WOW isn't implemented yet. RX rates stay fairly low
still.

Ping-Ke Shih kindly offered to add the required s-o-b for the firmware
and help get it into linux-firmware when it's time, for testing now
please see the code I used to extract firmware from the out-of-tree
driver [1].

Thanks to Ping-Ke Shih for advice, and Ondřej Jirman for debug logs!

[1] https://github.com/airtower-luna/rtw8703b-fw-extractor

v2:
* Parse PHY status using struct instead of macros
* Prefer MAC from EFUSE if available, move retrieving MAC from DT to
a separate function
* Tidy up wait for IQK to be done, replace mdelay loop with
read_poll_timeout
* Set dual author for rtw88_8723x
* Add missing "static" to rtw8723x function declarations, fixes
build failure when not built as a module
* Various style fixes

v3 has only minor changes requested in review, so I hope it's good to
merge now:
* rtw8703b.h: #include rtw8723x.h instead of linux/types.h and
linux/compiler_attributes.h
* rtw8703b_tables.c: #include rtw8703b_tables.h
* rtw8703b.c: define TRANS_SEQ_END without braces (checkpatch.pl
doesn't like this, but I assume maintainer request overrides it)

v4:
* Move definition of GET_RX_DESC_BW from rtw8703b.c to rx.h (now in
patch 3/9 "wifi: rtw88: Add definitions for 8703b chip")

Fiona Klute (9):
wifi: rtw88: Shared module for rtw8723x devices
wifi: rtw88: Debug output for rtw8723x EFUSE
wifi: rtw88: Add definitions for 8703b chip
wifi: rtw88: Add rtw8703b.h
wifi: rtw88: Add rtw8703b.c
wifi: rtw88: Add rtw8703b_tables.h
wifi: rtw88: Add rtw8703b_tables.c
wifi: rtw88: Reset 8703b firmware before download
wifi: rtw88: SDIO device driver for RTL8723CS

drivers/net/wireless/realtek/rtw88/Kconfig | 22 +
drivers/net/wireless/realtek/rtw88/Makefile | 9 +
drivers/net/wireless/realtek/rtw88/mac.c | 6 +
drivers/net/wireless/realtek/rtw88/main.h | 3 +
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2109 +++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8703b.h | 102 +
.../wireless/realtek/rtw88/rtw8703b_tables.c | 902 +++++++
.../wireless/realtek/rtw88/rtw8703b_tables.h | 14 +
.../net/wireless/realtek/rtw88/rtw8723cs.c | 34 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 673 +-----
drivers/net/wireless/realtek/rtw88/rtw8723d.h | 269 +--
drivers/net/wireless/realtek/rtw88/rtw8723x.c | 721 ++++++
drivers/net/wireless/realtek/rtw88/rtw8723x.h | 518 ++++
drivers/net/wireless/realtek/rtw88/rx.h | 2 +
include/linux/mmc/sdio_ids.h | 1 +
15 files changed, 4485 insertions(+), 900 deletions(-)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.h
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723cs.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.h

--
2.43.0



2024-03-11 10:38:44

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 6/9] wifi: rtw88: Add rtw8703b_tables.h

Initialization table definitions for rtw8703b.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
.../net/wireless/realtek/rtw88/rtw8703b_tables.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h
new file mode 100644
index 00000000000..98bd399bddb
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright Fiona Klute <[email protected]> */
+
+#ifndef __RTW8703B_TABLES_H__
+#define __RTW8703B_TABLES_H__
+
+extern const struct rtw_table rtw8703b_bb_pg_tbl;
+extern const struct rtw_table rtw8703b_txpwr_lmt_tbl;
+extern const struct rtw_table rtw8703b_mac_tbl;
+extern const struct rtw_table rtw8703b_agc_tbl;
+extern const struct rtw_table rtw8703b_bb_tbl;
+extern const struct rtw_table rtw8703b_rf_a_tbl;
+
+#endif
--
2.43.0


2024-03-11 10:39:09

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 7/9] wifi: rtw88: Add rtw8703b_tables.c

Initialization tables for rtw8703b: Initial register values and TX
power limits.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
.../wireless/realtek/rtw88/rtw8703b_tables.c | 902 ++++++++++++++++++
1 file changed, 902 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c
new file mode 100644
index 00000000000..81020fd907a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c
@@ -0,0 +1,902 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright Fiona Klute <[email protected]> */
+
+#include "main.h"
+#include "phy.h"
+#include "rtw8703b_tables.h"
+
+static const struct rtw_phy_pg_cfg_pair rtw8703b_bb_pg[] = {
+ { 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, },
+ { 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, },
+ { 0, 0, 0, 0x00000e00, 0xffffffff, 0x34363636, },
+ { 0, 0, 0, 0x00000e04, 0xffffffff, 0x28303234, },
+ { 0, 0, 0, 0x00000e10, 0xffffffff, 0x30343434, },
+ { 0, 0, 0, 0x00000e14, 0xffffffff, 0x26262830, },
+};
+
+RTW_DECL_TABLE_BB_PG(rtw8703b_bb_pg);
+
+/* Regd: FCC -> 0, ETSI -> 2, MKK -> 1
+ * Band: 2.4G -> 0, 5G -> 1
+ * Bandwidth (bw): 20M -> 0, 40M -> 1, 80M -> 2, 160M -> 3
+ * Rate Section (rs): CCK -> 0, OFDM -> 1, HT -> 2, VHT -> 3
+ */
+static const struct rtw_txpwr_lmt_cfg_pair rtw8703b_txpwr_lmt[] = {
+ {0, 0, 0, 0, 1, 30},
+ {2, 0, 0, 0, 1, 26},
+ {1, 0, 0, 0, 1, 32},
+ {0, 0, 0, 0, 2, 30},
+ {2, 0, 0, 0, 2, 26},
+ {1, 0, 0, 0, 2, 32},
+ {0, 0, 0, 0, 3, 30},
+ {2, 0, 0, 0, 3, 26},
+ {1, 0, 0, 0, 3, 32},
+ {0, 0, 0, 0, 4, 30},
+ {2, 0, 0, 0, 4, 26},
+ {1, 0, 0, 0, 4, 32},
+ {0, 0, 0, 0, 5, 30},
+ {2, 0, 0, 0, 5, 26},
+ {1, 0, 0, 0, 5, 32},
+ {0, 0, 0, 0, 6, 30},
+ {2, 0, 0, 0, 6, 26},
+ {1, 0, 0, 0, 6, 32},
+ {0, 0, 0, 0, 7, 30},
+ {2, 0, 0, 0, 7, 26},
+ {1, 0, 0, 0, 7, 32},
+ {0, 0, 0, 0, 8, 30},
+ {2, 0, 0, 0, 8, 26},
+ {1, 0, 0, 0, 8, 32},
+ {0, 0, 0, 0, 9, 30},
+ {2, 0, 0, 0, 9, 26},
+ {1, 0, 0, 0, 9, 32},
+ {0, 0, 0, 0, 10, 30},
+ {2, 0, 0, 0, 10, 26},
+ {1, 0, 0, 0, 10, 32},
+ {0, 0, 0, 0, 11, 30},
+ {2, 0, 0, 0, 11, 26},
+ {1, 0, 0, 0, 11, 32},
+ {0, 0, 0, 0, 12, 63},
+ {2, 0, 0, 0, 12, 26},
+ {1, 0, 0, 0, 12, 32},
+ {0, 0, 0, 0, 13, 63},
+ {2, 0, 0, 0, 13, 26},
+ {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, 28},
+ {2, 0, 0, 1, 1, 28},
+ {1, 0, 0, 1, 1, 28},
+ {0, 0, 0, 1, 2, 28},
+ {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, 32},
+ {2, 0, 0, 1, 9, 32},
+ {1, 0, 0, 1, 9, 32},
+ {0, 0, 0, 1, 10, 28},
+ {2, 0, 0, 1, 10, 32},
+ {1, 0, 0, 1, 10, 32},
+ {0, 0, 0, 1, 11, 28},
+ {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, 28},
+ {1, 0, 0, 1, 13, 28},
+ {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, 28},
+ {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, 32},
+ {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, 63},
+ {2, 0, 0, 2, 12, 32},
+ {1, 0, 0, 2, 12, 32},
+ {0, 0, 0, 2, 13, 63},
+ {2, 0, 0, 2, 13, 26},
+ {1, 0, 0, 2, 13, 28},
+ {0, 0, 0, 2, 14, 63},
+ {2, 0, 0, 2, 14, 63},
+ {1, 0, 0, 2, 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, 26},
+ {0, 0, 1, 2, 4, 26},
+ {2, 0, 1, 2, 4, 28},
+ {1, 0, 1, 2, 4, 26},
+ {0, 0, 1, 2, 5, 28},
+ {2, 0, 1, 2, 5, 28},
+ {1, 0, 1, 2, 5, 26},
+ {0, 0, 1, 2, 6, 28},
+ {2, 0, 1, 2, 6, 28},
+ {1, 0, 1, 2, 6, 26},
+ {0, 0, 1, 2, 7, 28},
+ {2, 0, 1, 2, 7, 28},
+ {1, 0, 1, 2, 7, 26},
+ {0, 0, 1, 2, 8, 26},
+ {2, 0, 1, 2, 8, 28},
+ {1, 0, 1, 2, 8, 26},
+ {0, 0, 1, 2, 9, 26},
+ {2, 0, 1, 2, 9, 28},
+ {1, 0, 1, 2, 9, 26},
+ {0, 0, 1, 2, 10, 26},
+ {2, 0, 1, 2, 10, 28},
+ {1, 0, 1, 2, 10, 26},
+ {0, 0, 1, 2, 11, 26},
+ {2, 0, 1, 2, 11, 26},
+ {1, 0, 1, 2, 11, 26},
+ {0, 0, 1, 2, 12, 63},
+ {2, 0, 1, 2, 12, 26},
+ {1, 0, 1, 2, 12, 26},
+ {0, 0, 1, 2, 13, 63},
+ {2, 0, 1, 2, 13, 26},
+ {1, 0, 1, 2, 13, 26},
+ {0, 0, 1, 2, 14, 63},
+ {2, 0, 1, 2, 14, 63},
+ {1, 0, 1, 2, 14, 63},
+};
+
+RTW_DECL_TABLE_TXPWR_LMT(rtw8703b_txpwr_lmt);
+
+static const u32 rtw8703b_mac[] = {
+ 0x02F, 0x00000030,
+ 0x035, 0x00000000,
+ 0x067, 0x00000002,
+ 0x092, 0x00000080,
+ 0x421, 0x0000000F,
+ 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,
+ 0x456, 0x0000005E,
+ 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, 0x00000028,
+ 0x55D, 0x000000FF,
+ 0x605, 0x00000030,
+ 0x608, 0x0000000E,
+ 0x609, 0x0000002A,
+ 0x620, 0x000000FF,
+ 0x621, 0x000000FF,
+ 0x622, 0x000000FF,
+ 0x623, 0x000000FF,
+ 0x624, 0x000000FF,
+ 0x625, 0x000000FF,
+ 0x626, 0x000000FF,
+ 0x627, 0x000000FF,
+ 0x638, 0x00000028,
+ 0x63C, 0x0000000A,
+ 0x63D, 0x0000000A,
+ 0x63E, 0x0000000C,
+ 0x63F, 0x0000000C,
+ 0x640, 0x00000040,
+ 0x642, 0x00000040,
+ 0x643, 0x00000000,
+ 0x652, 0x000000C8,
+ 0x66A, 0x000000B0,
+ 0x66E, 0x00000005,
+ 0x700, 0x00000021,
+ 0x701, 0x00000043,
+ 0x702, 0x00000065,
+ 0x703, 0x00000087,
+ 0x708, 0x00000021,
+ 0x709, 0x00000043,
+ 0x70A, 0x00000065,
+ 0x70B, 0x00000087,
+ 0x765, 0x00000018,
+ 0x76E, 0x00000004,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8703b_mac, rtw_phy_cfg_mac);
+
+static const u32 rtw8703b_agc[] = {
+ 0xC78, 0xFC000101,
+ 0xC78, 0xFB010101,
+ 0xC78, 0xFA020101,
+ 0xC78, 0xF9030101,
+ 0xC78, 0xF8040101,
+ 0xC78, 0xF7050101,
+ 0xC78, 0xF6060101,
+ 0xC78, 0xF5070101,
+ 0xC78, 0xF4080101,
+ 0xC78, 0xF3090101,
+ 0xC78, 0xF20A0101,
+ 0xC78, 0xF10B0101,
+ 0xC78, 0xF00C0101,
+ 0xC78, 0xEF0D0101,
+ 0xC78, 0xEE0E0101,
+ 0xC78, 0xED0F0101,
+ 0xC78, 0xEC100101,
+ 0xC78, 0xEB110101,
+ 0xC78, 0xEA120101,
+ 0xC78, 0xE9130101,
+ 0xC78, 0xE8140101,
+ 0xC78, 0xE7150101,
+ 0xC78, 0xE6160101,
+ 0xC78, 0xE5170101,
+ 0xC78, 0xE4180101,
+ 0xC78, 0xE3190101,
+ 0xC78, 0x661A0101,
+ 0xC78, 0x651B0101,
+ 0xC78, 0x641C0101,
+ 0xC78, 0x631D0101,
+ 0xC78, 0x071E0101,
+ 0xC78, 0x061F0101,
+ 0xC78, 0x05200101,
+ 0xC78, 0x04210101,
+ 0xC78, 0x03220101,
+ 0xC78, 0xE8230001,
+ 0xC78, 0xE7240001,
+ 0xC78, 0xE6250001,
+ 0xC78, 0xE5260001,
+ 0xC78, 0xE4270001,
+ 0xC78, 0x89280001,
+ 0xC78, 0x88290001,
+ 0xC78, 0x872A0001,
+ 0xC78, 0x862B0001,
+ 0xC78, 0x852C0001,
+ 0xC78, 0x482D0001,
+ 0xC78, 0x472E0001,
+ 0xC78, 0x462F0001,
+ 0xC78, 0x45300001,
+ 0xC78, 0x44310001,
+ 0xC78, 0x07320001,
+ 0xC78, 0x06330001,
+ 0xC78, 0x05340001,
+ 0xC78, 0x04350001,
+ 0xC78, 0x03360001,
+ 0xC78, 0x02370001,
+ 0xC78, 0x01380001,
+ 0xC78, 0x00390001,
+ 0xC78, 0x003A0001,
+ 0xC78, 0x003B0001,
+ 0xC78, 0x003C0001,
+ 0xC78, 0x003D0001,
+ 0xC78, 0x003E0001,
+ 0xC78, 0x003F0001,
+ 0xC78, 0x7F002001,
+ 0xC78, 0x7F012001,
+ 0xC78, 0x7F022001,
+ 0xC78, 0x7F032001,
+ 0xC78, 0x7F042001,
+ 0xC78, 0x7F052001,
+ 0xC78, 0x7F062001,
+ 0xC78, 0x7F072001,
+ 0xC78, 0x7F082001,
+ 0xC78, 0x7F092001,
+ 0xC78, 0x7F0A2001,
+ 0xC78, 0x7F0B2001,
+ 0xC78, 0x7F0C2001,
+ 0xC78, 0x7F0D2001,
+ 0xC78, 0x7F0E2001,
+ 0xC78, 0x7F0F2001,
+ 0xC78, 0x7F102001,
+ 0xC78, 0x7F112001,
+ 0xC78, 0x7E122001,
+ 0xC78, 0x7D132001,
+ 0xC78, 0x7C142001,
+ 0xC78, 0x7B152001,
+ 0xC78, 0x7A162001,
+ 0xC78, 0x79172001,
+ 0xC78, 0x78182001,
+ 0xC78, 0x77192001,
+ 0xC78, 0x761A2001,
+ 0xC78, 0x751B2001,
+ 0xC78, 0x741C2001,
+ 0xC78, 0x731D2001,
+ 0xC78, 0x721E2001,
+ 0xC78, 0x711F2001,
+ 0xC78, 0x70202001,
+ 0xC78, 0x6F212001,
+ 0xC78, 0x6E222001,
+ 0xC78, 0x6D232001,
+ 0xC78, 0x6C242001,
+ 0xC78, 0x6B252001,
+ 0xC78, 0x6A262001,
+ 0xC78, 0x69272001,
+ 0xC78, 0x68282001,
+ 0xC78, 0x67292001,
+ 0xC78, 0x662A2001,
+ 0xC78, 0x652B2001,
+ 0xC78, 0x642C2001,
+ 0xC78, 0x632D2001,
+ 0xC78, 0x622E2001,
+ 0xC78, 0x612F2001,
+ 0xC78, 0x60302001,
+ 0xC78, 0x42312001,
+ 0xC78, 0x41322001,
+ 0xC78, 0x40332001,
+ 0xC78, 0x23342001,
+ 0xC78, 0x22352001,
+ 0xC78, 0x21362001,
+ 0xC78, 0x20372001,
+ 0xC78, 0x00382001,
+ 0xC78, 0x02392001,
+ 0xC78, 0x013A2001,
+ 0xC78, 0x003B2001,
+ 0xC78, 0x003C2001,
+ 0xC78, 0x003D2001,
+ 0xC78, 0x003E2001,
+ 0xC78, 0x003F2001,
+ 0xC78, 0x7F003101,
+ 0xC78, 0x7F013101,
+ 0xC78, 0x7F023101,
+ 0xC78, 0x7F033101,
+ 0xC78, 0x7F043101,
+ 0xC78, 0x7F053101,
+ 0xC78, 0x7F063101,
+ 0xC78, 0x7E073101,
+ 0xC78, 0x7D083101,
+ 0xC78, 0x7C093101,
+ 0xC78, 0x7B0A3101,
+ 0xC78, 0x7A0B3101,
+ 0xC78, 0x790C3101,
+ 0xC78, 0x780D3101,
+ 0xC78, 0x770E3101,
+ 0xC78, 0x760F3101,
+ 0xC78, 0x75103101,
+ 0xC78, 0x74113101,
+ 0xC78, 0x73123101,
+ 0xC78, 0x72133101,
+ 0xC78, 0x71143101,
+ 0xC78, 0x70153101,
+ 0xC78, 0x6F163101,
+ 0xC78, 0x69173101,
+ 0xC78, 0x68183101,
+ 0xC78, 0x67193101,
+ 0xC78, 0x661A3101,
+ 0xC78, 0x651B3101,
+ 0xC78, 0x641C3101,
+ 0xC78, 0x631D3101,
+ 0xC78, 0x621E3101,
+ 0xC78, 0x611F3101,
+ 0xC78, 0x60203101,
+ 0xC78, 0x42213101,
+ 0xC78, 0x41223101,
+ 0xC78, 0x40233101,
+ 0xC78, 0x22243101,
+ 0xC78, 0x21253101,
+ 0xC78, 0x20263101,
+ 0xC78, 0x00273101,
+ 0xC78, 0x00283101,
+ 0xC78, 0x00293101,
+ 0xC78, 0x002A3101,
+ 0xC78, 0x002B3101,
+ 0xC78, 0x002C3101,
+ 0xC78, 0x002D3101,
+ 0xC78, 0x002E3101,
+ 0xC78, 0x002F3101,
+ 0xC78, 0x00303101,
+ 0xC78, 0x00313101,
+ 0xC78, 0x00323101,
+ 0xC78, 0x00333101,
+ 0xC78, 0x00343101,
+ 0xC78, 0x00353101,
+ 0xC78, 0x00363101,
+ 0xC78, 0x00373101,
+ 0xC78, 0x00383101,
+ 0xC78, 0x00393101,
+ 0xC78, 0x003A3101,
+ 0xC78, 0x003B3101,
+ 0xC78, 0x003C3101,
+ 0xC78, 0x003D3101,
+ 0xC78, 0x003E3101,
+ 0xC78, 0x003F3101,
+ 0xC78, 0xFA403101,
+ 0xC78, 0xF9413101,
+ 0xC78, 0xF8423101,
+ 0xC78, 0xF7433101,
+ 0xC78, 0xF6443101,
+ 0xC78, 0xF5453101,
+ 0xC78, 0xF4463101,
+ 0xC78, 0xF3473101,
+ 0xC78, 0xF2483101,
+ 0xC78, 0xE1493101,
+ 0xC78, 0xE04A3101,
+ 0xC78, 0xEF4B3101,
+ 0xC78, 0xEE4C3101,
+ 0xC78, 0xED4D3101,
+ 0xC78, 0xEC4E3101,
+ 0xC78, 0xEB4F3101,
+ 0xC78, 0xEA503101,
+ 0xC78, 0xE9513101,
+ 0xC78, 0xE8523101,
+ 0xC78, 0xE7533101,
+ 0xC78, 0xE6543101,
+ 0xC78, 0xE5553101,
+ 0xC78, 0xE4563101,
+ 0xC78, 0xE3573101,
+ 0xC78, 0xE2583101,
+ 0xC78, 0xE1593101,
+ 0xC78, 0xE05A3101,
+ 0xC78, 0xC25B3101,
+ 0xC78, 0xC15C3101,
+ 0xC78, 0xC05D3101,
+ 0xC78, 0x825E3101,
+ 0xC78, 0x815F3101,
+ 0xC78, 0x80603101,
+ 0xC78, 0x80613101,
+ 0xC78, 0x80623101,
+ 0xC78, 0x80633101,
+ 0xC78, 0x80643101,
+ 0xC78, 0x80653101,
+ 0xC78, 0x80663101,
+ 0xC78, 0x80673101,
+ 0xC78, 0x80683101,
+ 0xC78, 0x80693101,
+ 0xC78, 0x806A3101,
+ 0xC78, 0x806B3101,
+ 0xC78, 0x806C3101,
+ 0xC78, 0x806D3101,
+ 0xC78, 0x806E3101,
+ 0xC78, 0x806F3101,
+ 0xC78, 0x80703101,
+ 0xC78, 0x80713101,
+ 0xC78, 0x80723101,
+ 0xC78, 0x80733101,
+ 0xC78, 0x80743101,
+ 0xC78, 0x80753101,
+ 0xC78, 0x80763101,
+ 0xC78, 0x80773101,
+ 0xC78, 0x80783101,
+ 0xC78, 0x80793101,
+ 0xC78, 0x807A3101,
+ 0xC78, 0x807B3101,
+ 0xC78, 0x807C3101,
+ 0xC78, 0x807D3101,
+ 0xC78, 0x807E3101,
+ 0xC78, 0x807F3101,
+ 0xC78, 0xFF402001,
+ 0xC78, 0xFF412001,
+ 0xC78, 0xFF422001,
+ 0xC78, 0xFF432001,
+ 0xC78, 0xFF442001,
+ 0xC78, 0xFF452001,
+ 0xC78, 0xFF462001,
+ 0xC78, 0xFF472001,
+ 0xC78, 0xFF482001,
+ 0xC78, 0xFF492001,
+ 0xC78, 0xFF4A2001,
+ 0xC78, 0xFF4B2001,
+ 0xC78, 0xFF4C2001,
+ 0xC78, 0xFE4D2001,
+ 0xC78, 0xFD4E2001,
+ 0xC78, 0xFC4F2001,
+ 0xC78, 0xFB502001,
+ 0xC78, 0xFA512001,
+ 0xC78, 0xF9522001,
+ 0xC78, 0xF8532001,
+ 0xC78, 0xF7542001,
+ 0xC78, 0xF6552001,
+ 0xC78, 0xF5562001,
+ 0xC78, 0xF4572001,
+ 0xC78, 0xF3582001,
+ 0xC78, 0xF2592001,
+ 0xC78, 0xF15A2001,
+ 0xC78, 0xF05B2001,
+ 0xC78, 0xEF5C2001,
+ 0xC78, 0xEE5D2001,
+ 0xC78, 0xED5E2001,
+ 0xC78, 0xEC5F2001,
+ 0xC78, 0xEB602001,
+ 0xC78, 0xEA612001,
+ 0xC78, 0xE9622001,
+ 0xC78, 0xE8632001,
+ 0xC78, 0xE7642001,
+ 0xC78, 0xE6652001,
+ 0xC78, 0xE5662001,
+ 0xC78, 0xE4672001,
+ 0xC78, 0xE3682001,
+ 0xC78, 0xC5692001,
+ 0xC78, 0xC46A2001,
+ 0xC78, 0xC36B2001,
+ 0xC78, 0xA46C2001,
+ 0xC78, 0x846D2001,
+ 0xC78, 0x836E2001,
+ 0xC78, 0x826F2001,
+ 0xC78, 0x81702001,
+ 0xC78, 0x80712001,
+ 0xC78, 0x80722001,
+ 0xC78, 0x80732001,
+ 0xC78, 0x80742001,
+ 0xC78, 0x80752001,
+ 0xC78, 0x80762001,
+ 0xC78, 0x80772001,
+ 0xC78, 0x80782001,
+ 0xC78, 0x80792001,
+ 0xC78, 0x807A2001,
+ 0xC78, 0x807B2001,
+ 0xC78, 0x807C2001,
+ 0xC78, 0x807D2001,
+ 0xC78, 0x807E2001,
+ 0xC78, 0x807F2001,
+ 0xC50, 0x69553422,
+ 0xC50, 0x69553420,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8703b_agc, rtw_phy_cfg_agc);
+
+/* init values for BB registers */
+static const u32 rtw8703b_bb[] = {
+ 0x800, 0x83045700,
+ 0x804, 0x00000003,
+ 0x808, 0x0000FC00,
+ 0x80C, 0x0000000A,
+ 0x810, 0x10001331,
+ 0x814, 0x020C3D10,
+ 0x818, 0x02200385,
+ 0x81C, 0x00000000,
+ 0x820, 0x01000100,
+ 0x824, 0x00390204,
+ 0x828, 0x00000000,
+ 0x82C, 0x00000000,
+ 0x830, 0x00000000,
+ 0x834, 0x00000000,
+ 0x838, 0x00000000,
+ 0x83C, 0x00000000,
+ 0x840, 0x00010000,
+ 0x844, 0x00000000,
+ 0x848, 0x00000000,
+ 0x84C, 0x00000000,
+ 0x850, 0x00000000,
+ 0x854, 0x00000000,
+ 0x858, 0x569A11A9,
+ 0x85C, 0x01000014,
+ 0x860, 0x66F60110,
+ 0x864, 0x061F0649,
+ 0x868, 0x00000000,
+ 0x86C, 0x27272700,
+ 0x870, 0x07000760,
+ 0x874, 0x25004000,
+ 0x878, 0x00000808,
+ 0x87C, 0x004F0201,
+ 0x880, 0xB0000B1E,
+ 0x884, 0x00000001,
+ 0x888, 0x00000000,
+ 0x88C, 0xCCC000C0,
+ 0x890, 0x00000800,
+ 0x894, 0xFFFFFFFE,
+ 0x898, 0x40302010,
+ 0x89C, 0x00706050,
+ 0x900, 0x00000000,
+ 0x904, 0x00000023,
+ 0x908, 0x00000000,
+ 0x90C, 0x81121111,
+ 0x910, 0x00000002,
+ 0x914, 0x00000201,
+ 0x948, 0x99000000,
+ 0x94C, 0x00000010,
+ 0x950, 0x20003800,
+ 0x954, 0x4A880000,
+ 0x958, 0x4BC5D87A,
+ 0x95C, 0x04EB9B79,
+ 0xA00, 0x00D047C8,
+ 0xA04, 0x80FF800C,
+ 0xA08, 0x8C838300,
+ 0xA0C, 0x2E7F120F,
+ 0xA10, 0x9500BB78,
+ 0xA14, 0x1114D028,
+ 0xA18, 0x00881117,
+ 0xA1C, 0x89140F00,
+ 0xA20, 0xD1D80000,
+ 0xA24, 0x5A7DA0BD,
+ 0xA28, 0x0000223B,
+ 0xA2C, 0x00D30000,
+ 0xA70, 0x101FBF00,
+ 0xA74, 0x00000007,
+ 0xA78, 0x00008900,
+ 0xA7C, 0x225B0606,
+ 0xA80, 0x2180FA74,
+ 0xA84, 0x00120000,
+ 0xA88, 0x040C0000,
+ 0xA8C, 0x12345678,
+ 0xA90, 0xABCDEF00,
+ 0xA94, 0x001B1B89,
+ 0xA98, 0x05100000,
+ 0xA9C, 0x3F000000,
+ 0xAA0, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0xC00, 0x48071D40,
+ 0xC04, 0x03A05611,
+ 0xC08, 0x000000E4,
+ 0xC0C, 0x6C6C6C6C,
+ 0xC10, 0x18800000,
+ 0xC14, 0x40000100,
+ 0xC18, 0x08800000,
+ 0xC1C, 0x40000100,
+ 0xC20, 0x00000000,
+ 0xC24, 0x00000000,
+ 0xC28, 0x00000000,
+ 0xC2C, 0x00000000,
+ 0xC30, 0x69E9AC4B,
+ 0xC34, 0x31000040,
+ 0xC38, 0x21688080,
+ 0xC3C, 0x000016CC,
+ 0xC40, 0x1F78403F,
+ 0xC44, 0x00010036,
+ 0xC48, 0xEC020107,
+ 0xC4C, 0x007F037F,
+ 0xC50, 0x69553420,
+ 0xC54, 0x43BC0094,
+ 0xC58, 0x00015967,
+ 0xC5C, 0x18250492,
+ 0xC60, 0x00000000,
+ 0xC64, 0x7112848B,
+ 0xC68, 0x47C07BFF,
+ 0xC6C, 0x00000036,
+ 0xC70, 0x2C7F000D,
+ 0xC74, 0x020600DB,
+ 0xC78, 0x0000001F,
+ 0xC7C, 0x00B91612,
+ 0xC80, 0x390000E4,
+ 0xC84, 0x19F60000,
+ 0xC88, 0x40000100,
+ 0xC8C, 0x20200000,
+ 0xC90, 0x00091521,
+ 0xC94, 0x00000000,
+ 0xC98, 0x00121820,
+ 0xC9C, 0x00007F7F,
+ 0xCA0, 0x00000000,
+ 0xCA4, 0x000300A0,
+ 0xCA8, 0x00000000,
+ 0xCAC, 0x00000000,
+ 0xCB0, 0x00000000,
+ 0xCB4, 0x00000000,
+ 0xCB8, 0x00000000,
+ 0xCBC, 0x28000000,
+ 0xCC0, 0x00000000,
+ 0xCC4, 0x00000000,
+ 0xCC8, 0x00000000,
+ 0xCCC, 0x00000000,
+ 0xCD0, 0x00000000,
+ 0xCD4, 0x00000000,
+ 0xCD8, 0x64B22427,
+ 0xCDC, 0x00766932,
+ 0xCE0, 0x00222222,
+ 0xCE4, 0x10000000,
+ 0xCE8, 0x37644302,
+ 0xCEC, 0x2F97D40C,
+ 0xD00, 0x00030740,
+ 0xD04, 0x40020401,
+ 0xD08, 0x0000907F,
+ 0xD0C, 0x20010201,
+ 0xD10, 0xA0633333,
+ 0xD14, 0x3333BC53,
+ 0xD18, 0x7A8F5B6F,
+ 0xD2C, 0xCB979975,
+ 0xD30, 0x00000000,
+ 0xD34, 0x80608000,
+ 0xD38, 0x98000000,
+ 0xD3C, 0x40127353,
+ 0xD40, 0x00000000,
+ 0xD44, 0x00000000,
+ 0xD48, 0x00000000,
+ 0xD4C, 0x00000000,
+ 0xD50, 0x6437140A,
+ 0xD54, 0x00000000,
+ 0xD58, 0x00000282,
+ 0xD5C, 0x30032064,
+ 0xD60, 0x4653DE68,
+ 0xD64, 0x04518A3C,
+ 0xD68, 0x00002101,
+ 0xE00, 0x2D2D2D2D,
+ 0xE04, 0x2D2D2D2D,
+ 0xE08, 0x0390272D,
+ 0xE10, 0x2D2D2D2D,
+ 0xE14, 0x2D2D2D2D,
+ 0xE18, 0x2D2D2D2D,
+ 0xE1C, 0x2D2D2D2D,
+ 0xE28, 0x00000000,
+ 0xE30, 0x1000DC1F,
+ 0xE34, 0x10008C1F,
+ 0xE38, 0x02140102,
+ 0xE3C, 0x681604C2,
+ 0xE40, 0x01007C00,
+ 0xE44, 0x01004800,
+ 0xE48, 0xFB000000,
+ 0xE4C, 0x000028D1,
+ 0xE50, 0x1000DC1F,
+ 0xE54, 0x10008C1F,
+ 0xE58, 0x02140102,
+ 0xE5C, 0x28160D05,
+ 0xE60, 0x00000048,
+ 0xE68, 0x001B25A4,
+ 0xE6C, 0x01C00014,
+ 0xE70, 0x01C00014,
+ 0xE74, 0x02000014,
+ 0xE78, 0x02000014,
+ 0xE7C, 0x02000014,
+ 0xE80, 0x02000014,
+ 0xE84, 0x01C00014,
+ 0xE88, 0x02000014,
+ 0xE8C, 0x01C00014,
+ 0xED0, 0x01C00014,
+ 0xED4, 0x01C00014,
+ 0xED8, 0x01C00014,
+ 0xEDC, 0x00000014,
+ 0xEE0, 0x00000014,
+ 0xEE8, 0x21555448,
+ 0xEEC, 0x03C00014,
+ 0xF14, 0x00000003,
+ 0xF4C, 0x00000000,
+ 0xF00, 0x00000300,
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8703b_bb, rtw_phy_cfg_bb);
+
+static const u32 rtw8703b_rf_a[] = {
+ 0x018, 0x00008C01,
+ 0x0B5, 0x0008C050,
+ 0x0B1, 0x00054258,
+ 0x0B2, 0x00054C00,
+ 0x030, 0x00018000,
+ 0x031, 0x00000027,
+ 0x032, 0x000A7F07,
+ 0x030, 0x00020000,
+ 0x031, 0x00000027,
+ 0x032, 0x000E7D87,
+ 0x01C, 0x000F8635,
+ 0x0EF, 0x00080000,
+ 0x030, 0x00008000,
+ 0x031, 0x00000004,
+ 0x032, 0x00006105,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00000400,
+ 0x041, 0x0000BD54,
+ 0x041, 0x00003DD4,
+ 0x041, 0x0000FDD4,
+ 0x0EF, 0x00000000,
+ 0x0DF, 0x00000600,
+ 0x050, 0x0000C6DB,
+ 0x051, 0x00004505,
+ 0x052, 0x0000E31D,
+ 0x053, 0x00040579,
+ 0x054, 0x00000000,
+ 0x055, 0x0008206E,
+ 0x056, 0x00040000,
+ 0x0EF, 0x00000100,
+ 0x034, 0x0000ADD7,
+ 0x034, 0x00009DD4,
+ 0x034, 0x00008DD1,
+ 0x034, 0x00007DCE,
+ 0x034, 0x00006DCB,
+ 0x034, 0x00005CCE,
+ 0x034, 0x000048CD,
+ 0x034, 0x000034CC,
+ 0x034, 0x0000244F,
+ 0x034, 0x0000144C,
+ 0x034, 0x0000004E,
+ 0x0EF, 0x00000000,
+ 0x0EF, 0x00002000,
+ 0x03B, 0x0003801F,
+ 0x03B, 0x00030002,
+ 0x03B, 0x00028001,
+ 0x03B, 0x00020000,
+ 0x03B, 0x00018003,
+ 0x03B, 0x00010002,
+ 0x03B, 0x00008001,
+ 0x03B, 0x00000000,
+ 0x0EF, 0x00000000,
+ 0x082, 0x000C0000,
+ 0x083, 0x000AF025,
+ 0x01E, 0x00000C08,
+};
+
+RTW_DECL_TABLE_RF_RADIO(rtw8703b_rf_a, A);
--
2.43.0


2024-03-11 10:39:10

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 8/9] wifi: rtw88: Reset 8703b firmware before download

Sometimes 8703b firmware is still active from previous use when the
driver needs to download the firmware during MAC activation. Reset it
in that case.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/mac.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 298663b0358..5fa38b1068e 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -936,6 +936,12 @@ static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev,
{
int ret = 0;

+ /* reset firmware if still present */
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B &&
+ rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) {
+ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00);
+ }
+
en_download_firmware_legacy(rtwdev, true);
ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size);
en_download_firmware_legacy(rtwdev, false);
--
2.43.0


2024-03-11 10:39:23

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 9/9] wifi: rtw88: SDIO device driver for RTL8723CS

This driver uses the new rtw8703b chip driver code.

Acked-by: Ping-Ke Shih <[email protected]>
Acked-by: Ulf Hansson <[email protected]> # For SDIO
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/Kconfig | 18 ++++++++++
drivers/net/wireless/realtek/rtw88/Makefile | 6 ++++
.../net/wireless/realtek/rtw88/rtw8723cs.c | 34 +++++++++++++++++++
include/linux/mmc/sdio_ids.h | 1 +
4 files changed, 59 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723cs.c

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 07b5b2f6eef..22838ede03c 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -31,6 +31,10 @@ config RTW88_8822C
config RTW88_8723X
tristate

+config RTW88_8703B
+ tristate
+ select RTW88_8723X
+
config RTW88_8723D
tristate
select RTW88_8723X
@@ -126,6 +130,20 @@ config RTW88_8723DS

802.11n SDIO wireless network adapter

+config RTW88_8723CS
+ tristate "Realtek 8723CS SDIO wireless network adapter"
+ depends on MMC
+ select RTW88_CORE
+ select RTW88_SDIO
+ select RTW88_8703B
+ help
+ Select this option to enable support for 8723CS chipset (EXPERIMENTAL)
+
+ This module adds support for the 8723CS 802.11n SDIO
+ wireless network adapter.
+
+ If you choose to build a module, it'll be called rtw88_8723cs.
+
config RTW88_8723DU
tristate "Realtek 8723DU USB wireless network adapter"
depends on USB
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 22516c98460..8f47359b438 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -47,6 +47,12 @@ rtw88_8822cu-objs := rtw8822cu.o
obj-$(CONFIG_RTW88_8723X) += rtw88_8723x.o
rtw88_8723x-objs := rtw8723x.o

+obj-$(CONFIG_RTW88_8703B) += rtw88_8703b.o
+rtw88_8703b-objs := rtw8703b.o rtw8703b_tables.o
+
+obj-$(CONFIG_RTW88_8723CS) += rtw88_8723cs.o
+rtw88_8723cs-objs := rtw8723cs.o
+
obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o
rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723cs.c b/drivers/net/wireless/realtek/rtw88/rtw8723cs.c
new file mode 100644
index 00000000000..8d38d36be8c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723cs.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright Fiona Klute <[email protected]> */
+
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/module.h>
+#include "main.h"
+#include "rtw8703b.h"
+#include "sdio.h"
+
+static const struct sdio_device_id rtw_8723cs_id_table[] = {
+ {
+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK,
+ SDIO_DEVICE_ID_REALTEK_RTW8723CS),
+ .driver_data = (kernel_ulong_t)&rtw8703b_hw_spec,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(sdio, rtw_8723cs_id_table);
+
+static struct sdio_driver rtw_8723cs_driver = {
+ .name = "rtw8723cs",
+ .id_table = rtw_8723cs_id_table,
+ .probe = rtw_sdio_probe,
+ .remove = rtw_sdio_remove,
+ .drv = {
+ .pm = &rtw_sdio_pm_ops,
+ .shutdown = rtw_sdio_shutdown
+ }};
+module_sdio_driver(rtw_8723cs_driver);
+
+MODULE_AUTHOR("Fiona Klute <[email protected]>");
+MODULE_DESCRIPTION("Realtek 802.11n wireless 8723cs driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 7fada7a714f..7cddfdac2f5 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -124,6 +124,7 @@
#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT 0xd723
#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT 0xd724
#define SDIO_DEVICE_ID_REALTEK_RTW8821DS 0xd821
+#define SDIO_DEVICE_ID_REALTEK_RTW8723CS 0xb703

#define SDIO_VENDOR_ID_SIANO 0x039a
#define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201
--
2.43.0


2024-03-11 10:39:24

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 1/9] wifi: rtw88: Shared module for rtw8723x devices

The already supported 8723d chip is very similar to 8703b/8723cs,
split code that can be shared into a new module. The spec definition
tables are combined into a struct so we only need one EXPORT_SYMBOL
for them all.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/Kconfig | 4 +
drivers/net/wireless/realtek/rtw88/Makefile | 3 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 673 ++----------------
drivers/net/wireless/realtek/rtw88/rtw8723d.h | 269 +------
drivers/net/wireless/realtek/rtw88/rtw8723x.c | 562 +++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8723x.h | 496 +++++++++++++
6 files changed, 1107 insertions(+), 900 deletions(-)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.c
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.h

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index cffad1c0124..07b5b2f6eef 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -28,8 +28,12 @@ config RTW88_8822B
config RTW88_8822C
tristate

+config RTW88_8723X
+ tristate
+
config RTW88_8723D
tristate
+ select RTW88_8723X

config RTW88_8821C
tristate
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index fd212c09d88..22516c98460 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -44,6 +44,9 @@ rtw88_8822cs-objs := rtw8822cs.o
obj-$(CONFIG_RTW88_8822CU) += rtw88_8822cu.o
rtw88_8822cu-objs := rtw8822cu.o

+obj-$(CONFIG_RTW88_8723X) += rtw88_8723x.o
+rtw88_8723x-objs := rtw8723x.o
+
obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o
rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index c575476a002..f8df4c84d39 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -9,36 +9,13 @@
#include "tx.h"
#include "rx.h"
#include "phy.h"
+#include "rtw8723x.h"
#include "rtw8723d.h"
#include "rtw8723d_table.h"
#include "mac.h"
#include "reg.h"
#include "debug.h"

-static const struct rtw_hw_reg rtw8723d_txagc[] = {
- [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 },
- [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 },
- [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 },
- [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 },
- [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff },
- [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 },
- [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 },
- [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 },
- [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff },
- [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 },
- [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 },
- [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 },
- [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff },
- [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 },
- [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 },
- [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 },
- [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff },
- [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 },
- [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 },
- [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 },
-};
-
-#define WLAN_TXQ_RPT_EN 0x1F
#define WLAN_SLOT_TIME 0x09
#define WLAN_RL_VAL 0x3030
#define WLAN_BAR_VAL 0x0201ffff
@@ -65,34 +42,6 @@ static const struct rtw_hw_reg rtw8723d_txagc[] = {
#define WLAN_LTR_CTRL1 0xCB004010
#define WLAN_LTR_CTRL2 0x01233425

-static void rtw8723d_lck(struct rtw_dev *rtwdev)
-{
- u32 lc_cal;
- u8 val_ctx, rf_val;
- int ret;
-
- val_ctx = rtw_read8(rtwdev, REG_CTX);
- if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
- rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE);
- else
- rtw_write8(rtwdev, REG_TXPAUSE, 0xFF);
- lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
-
- rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK);
-
- ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1,
- 10000, 1000000, false,
- rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK);
- if (ret)
- rtw_warn(rtwdev, "failed to poll LCK status bit\n");
-
- rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
- if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
- rtw_write8(rtwdev, REG_CTX, val_ctx);
- else
- rtw_write8(rtwdev, REG_TXPAUSE, 0x00);
-}
-
static const u32 rtw8723d_ofdm_swing_table[] = {
0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c,
0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056,
@@ -196,7 +145,7 @@ static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)

rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);

- rtw8723d_lck(rtwdev);
+ rtw8723x_lck(rtwdev);

rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20);
@@ -204,67 +153,6 @@ static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)
rtw8723d_pwrtrack_init(rtwdev);
}

-static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse,
- struct rtw8723d_efuse *map)
-{
- ether_addr_copy(efuse->addr, map->e.mac_addr);
-}
-
-static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse,
- struct rtw8723d_efuse *map)
-{
- ether_addr_copy(efuse->addr, map->u.mac_addr);
-}
-
-static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse,
- struct rtw8723d_efuse *map)
-{
- ether_addr_copy(efuse->addr, map->s.mac_addr);
-}
-
-static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
-{
- struct rtw_efuse *efuse = &rtwdev->efuse;
- struct rtw8723d_efuse *map;
- int i;
-
- map = (struct rtw8723d_efuse *)log_map;
-
- efuse->rfe_option = 0;
- efuse->rf_board_option = map->rf_board_option;
- efuse->crystal_cap = map->xtal_k;
- efuse->pa_type_2g = map->pa_type;
- efuse->lna_type_2g = map->lna_type_2g[0];
- 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_k = map->thermal_meter;
- efuse->afe = map->afe;
-
- 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_PCIE:
- rtw8723de_efuse_parsing(efuse, map);
- break;
- case RTW_HCI_TYPE_USB:
- rtw8723du_efuse_parsing(efuse, map);
- break;
- case RTW_HCI_TYPE_SDIO:
- rtw8723ds_efuse_parsing(efuse, map);
- break;
- default:
- /* unsupported now */
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
struct rtw_rx_pkt_stat *pkt_stat)
{
@@ -540,297 +428,11 @@ static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
}

-#define BIT_CFENDFORM BIT(9)
-#define BIT_WMAC_TCR_ERR0 BIT(12)
-#define BIT_WMAC_TCR_ERR1 BIT(13)
-#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \
- BIT_WMAC_TCR_ERR1)
-#define WLAN_RX_FILTER0 0xFFFF
-#define WLAN_RX_FILTER1 0x400
-#define WLAN_RX_FILTER2 0xFFFF
-#define WLAN_RCR_CFG 0x700060CE
-
-static int rtw8723d_mac_init(struct rtw_dev *rtwdev)
-{
- rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
- rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);
-
- rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
- rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1);
- rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
- rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
-
- rtw_write32(rtwdev, REG_INT_MIG, 0);
- rtw_write32(rtwdev, REG_MCUTST_1, 0x0);
-
- rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA);
- rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0);
-
- return 0;
-}
-
static void rtw8723d_shutdown(struct rtw_dev *rtwdev)
{
rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS);
}

-static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
-{
- u8 ldo_pwr;
-
- ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
- if (enable) {
- ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE;
- ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN;
- } else {
- ldo_pwr &= ~BIT_LDO25_EN;
- }
- rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
-}
-
-static void
-rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
-{
- struct rtw_hal *hal = &rtwdev->hal;
- const struct rtw_hw_reg *txagc;
- u8 rate, pwr_index;
- 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];
-
- if (rate >= ARRAY_SIZE(rtw8723d_txagc)) {
- rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate);
- continue;
- }
- txagc = &rtw8723d_txagc[rate];
- if (!txagc->addr) {
- rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate);
- continue;
- }
-
- rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index);
- }
-}
-
-static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev)
-{
- struct rtw_hal *hal = &rtwdev->hal;
- int rs, path;
-
- for (path = 0; path < hal->rf_path_num; path++) {
- for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++)
- rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs);
- }
-}
-
-static void rtw8723d_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 rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- u32 cck_fa_cnt;
- u32 ofdm_fa_cnt;
- u32 crc32_cnt;
- u32 val32;
-
- /* hold counter */
- rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);
- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);
- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);
- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);
-
- cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);
- cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;
-
- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);
- ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);
- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);
- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);
- dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);
- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);
- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);
- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);
- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);
- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);
- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);
-
- dm_info->cck_fa_cnt = cck_fa_cnt;
- dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
- dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;
-
- dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);
- dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);
- crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);
- dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);
- dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);
- crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);
- dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);
- dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);
- dm_info->vht_err_cnt = 0;
- dm_info->vht_ok_cnt = 0;
-
- val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);
- dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |
- u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);
- dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;
-
- /* reset counter */
- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);
- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);
- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);
- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);
- rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);
- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);
- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);
- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);
- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);
- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);
- rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);
- rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);
-}
-
-static const u32 iqk_adda_regs[] = {
- 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
- 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec
-};
-
-static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551};
-static const u32 iqk_mac32_regs[] = {0x40};
-
-static const u32 iqk_bb_regs[] = {
- 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04
-};
-
-#define IQK_ADDA_REG_NUM ARRAY_SIZE(iqk_adda_regs)
-#define IQK_MAC8_REG_NUM ARRAY_SIZE(iqk_mac8_regs)
-#define IQK_MAC32_REG_NUM ARRAY_SIZE(iqk_mac32_regs)
-#define IQK_BB_REG_NUM ARRAY_SIZE(iqk_bb_regs)
-
-struct iqk_backup_regs {
- u32 adda[IQK_ADDA_REG_NUM];
- u8 mac8[IQK_MAC8_REG_NUM];
- u32 mac32[IQK_MAC32_REG_NUM];
- u32 bb[IQK_BB_REG_NUM];
-
- u32 lte_path;
- u32 lte_gnt;
-
- u32 bb_sel_btg;
- u8 btg_sel;
-
- u8 igia;
- u8 igib;
-};
-
-static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev,
- struct iqk_backup_regs *backup)
-{
- int i;
-
- for (i = 0; i < IQK_ADDA_REG_NUM; i++)
- backup->adda[i] = rtw_read32(rtwdev, iqk_adda_regs[i]);
-
- for (i = 0; i < IQK_MAC8_REG_NUM; i++)
- backup->mac8[i] = rtw_read8(rtwdev, iqk_mac8_regs[i]);
- for (i = 0; i < IQK_MAC32_REG_NUM; i++)
- backup->mac32[i] = rtw_read32(rtwdev, iqk_mac32_regs[i]);
-
- for (i = 0; i < IQK_BB_REG_NUM; i++)
- backup->bb[i] = rtw_read32(rtwdev, iqk_bb_regs[i]);
-
- backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0);
- backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0);
-
- backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG);
-}
-
-static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev,
- const struct iqk_backup_regs *backup)
-{
- int i;
-
- for (i = 0; i < IQK_ADDA_REG_NUM; i++)
- rtw_write32(rtwdev, iqk_adda_regs[i], backup->adda[i]);
-
- for (i = 0; i < IQK_MAC8_REG_NUM; i++)
- rtw_write8(rtwdev, iqk_mac8_regs[i], backup->mac8[i]);
- for (i = 0; i < IQK_MAC32_REG_NUM; i++)
- rtw_write32(rtwdev, iqk_mac32_regs[i], backup->mac32[i]);
-
- for (i = 0; i < IQK_BB_REG_NUM; i++)
- rtw_write32(rtwdev, iqk_bb_regs[i], backup->bb[i]);
-
- rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
- rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia);
-
- rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50);
- rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib);
-
- rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00);
- rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);
-}
-
-static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev,
- struct iqk_backup_regs *backup)
-{
- backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL);
- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n",
- backup->btg_sel);
-}
-
-static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev)
-{
- rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1);
- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n",
- rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
-}
-
-static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev,
- const struct iqk_backup_regs *backup)
-{
- rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel);
- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n",
- rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
-}
-
-static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev,
- struct iqk_backup_regs *backup)
-{
- backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL);
- rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038);
- mdelay(1);
- backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA);
- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n",
- backup->lte_gnt);
-}
-
-static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev)
-{
- rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, 0x0000ff00);
- rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038);
- rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, 0x1);
-}
-
-static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev,
- const struct iqk_backup_regs *bak)
-{
- rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt);
- rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038);
- rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path);
-}
-
struct rtw_8723d_iqk_cfg {
const char *name;
u32 val_bb_sel_btg;
@@ -930,6 +532,8 @@ static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev,
return 0;
}

+#define IQK_LTE_WRITE_VAL_8723D 0x0000ff00
+
static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx,
const struct rtw_8723d_iqk_cfg *iqk_cfg)
{
@@ -937,7 +541,7 @@ static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx,

/* enter IQK mode */
rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
- rtw8723d_iqk_config_lte_path_gnt(rtwdev);
+ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D);

rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054);
mdelay(1);
@@ -959,9 +563,9 @@ static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx,

static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev,
const struct rtw_8723d_iqk_cfg *iqk_cfg,
- const struct iqk_backup_regs *backup)
+ const struct rtw8723x_iqk_backup_regs *backup)
{
- rtw8723d_iqk_restore_lte_path_gnt(rtwdev, backup);
+ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup);
rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg);

/* leave IQK mode */
@@ -974,7 +578,7 @@ static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev,

static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev,
const struct rtw_8723d_iqk_cfg *iqk_cfg,
- const struct iqk_backup_regs *backup)
+ const struct rtw8723x_iqk_backup_regs *backup)
{
u8 status;

@@ -1033,7 +637,7 @@ static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev,

static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev,
const struct rtw_8723d_iqk_cfg *iqk_cfg,
- const struct iqk_backup_regs *backup)
+ const struct rtw8723x_iqk_backup_regs *backup)
{
u32 tx_x, tx_y;
u8 status;
@@ -1220,14 +824,6 @@ void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[])
result[IQK_S0_RX_Y]);
}

-static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev)
-{
- int i;
-
- for (i = 0; i < IQK_ADDA_REG_NUM; i++)
- rtw_write32(rtwdev, iqk_adda_regs[i], 0x03c00016);
-}
-
static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev)
{
rtw_write8(rtwdev, REG_TXPAUSE, 0xff);
@@ -1245,70 +841,14 @@ void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path)
rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
}

-static
-bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR],
- u8 c1, u8 c2)
-{
- u32 i, j, diff;
- u32 bitmap = 0;
- u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID};
- bool ret = true;
-
- s32 tmp1, tmp2;
-
- for (i = 0; i < IQK_NR; i++) {
- tmp1 = iqkxy_to_s32(result[c1][i]);
- tmp2 = iqkxy_to_s32(result[c2][i]);
-
- diff = abs(tmp1 - tmp2);
-
- if (diff <= MAX_TOLERANCE)
- continue;
-
- if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) {
- if (result[c1][i] + result[c1][i + 1] == 0)
- candidate[i / IQK_SX_NR] = c2;
- else if (result[c2][i] + result[c2][i + 1] == 0)
- candidate[i / IQK_SX_NR] = c1;
- else
- bitmap |= BIT(i);
- } else {
- bitmap |= BIT(i);
- }
- }
-
- if (bitmap != 0)
- goto check_sim;
-
- for (i = 0; i < PATH_NR; i++) {
- if (candidate[i] == IQK_ROUND_INVALID)
- continue;
-
- for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++)
- result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j];
- ret = false;
- }
-
- return ret;
-
-check_sim:
- for (i = 0; i < IQK_NR; i++) {
- j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */
- if (bitmap & GENMASK(j + 1, j))
- continue;
-
- result[IQK_ROUND_HYBRID][i] = result[c1][i];
- }
-
- return false;
-}
+#define ADDA_ON_VAL_8723D 0x03c00016

static
-void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path)
+void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723x_path path)
{
if (path == PATH_S0) {
rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A);
- rtw8723d_iqk_path_adda_on(rtwdev);
+ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D);
}

rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
@@ -1317,13 +857,13 @@ void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path)

if (path == PATH_S1) {
rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B);
- rtw8723d_iqk_path_adda_on(rtwdev);
+ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D);
}
}

static
void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,
- const struct iqk_backup_regs *backup)
+ const struct rtw8723x_iqk_backup_regs *backup)
{
u32 i;
u8 s1_ok, s0_ok;
@@ -1331,7 +871,7 @@ void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,
rtw_dbg(rtwdev, RTW_DBG_RFK,
"[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t);

- rtw8723d_iqk_path_adda_on(rtwdev);
+ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D);
rtw8723d_iqk_config_mac(rtwdev);
rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf);
rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611);
@@ -1427,7 +967,7 @@ static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
s32 result[IQK_ROUND_SIZE][IQK_NR];
- struct iqk_backup_regs backup;
+ struct rtw8723x_iqk_backup_regs backup;
u8 i, j;
u8 final_candidate = IQK_ROUND_INVALID;
bool good;
@@ -1436,23 +976,23 @@ static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev)

memset(result, 0, sizeof(result));

- rtw8723d_iqk_backup_path_ctrl(rtwdev, &backup);
- rtw8723d_iqk_backup_lte_path_gnt(rtwdev, &backup);
- rtw8723d_iqk_backup_regs(rtwdev, &backup);
+ rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup);
+ rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup);
+ rtw8723x_iqk_backup_regs(rtwdev, &backup);

for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) {
- rtw8723d_iqk_config_path_ctrl(rtwdev);
- rtw8723d_iqk_config_lte_path_gnt(rtwdev);
+ rtw8723x_iqk_config_path_ctrl(rtwdev);
+ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D);

rtw8723d_iqk_one_round(rtwdev, result, i, &backup);

if (i > IQK_ROUND_0)
- rtw8723d_iqk_restore_regs(rtwdev, &backup);
- rtw8723d_iqk_restore_lte_path_gnt(rtwdev, &backup);
- rtw8723d_iqk_restore_path_ctrl(rtwdev, &backup);
+ rtw8723x_iqk_restore_regs(rtwdev, &backup);
+ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup);
+ rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup);

for (j = IQK_ROUND_0; j < i; j++) {
- good = rtw8723d_iqk_similarity_cmp(rtwdev, result, j, i);
+ good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i);

if (good) {
final_candidate = j;
@@ -1546,26 +1086,6 @@ static void rtw8723d_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
}

/* for coex */
-static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev)
-{
- /* enable TBTT nterrupt */
- rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
-
- /* BT report packet sample rate */
- /* 0x790[5:0]=0x5 */
- rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
-
- /* enable BT counter statistics */
- rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
-
- /* enable PTA (3-wire function form BT side) */
- rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
- rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
-
- /* enable PTA (tx/rx signal form WiFi side) */
- rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
-}
-
static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
{
}
@@ -1671,39 +1191,6 @@ static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
}
}

-static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- u8 tx_rate = dm_info->tx_rate;
- u8 limit_ofdm = 30;
-
- switch (tx_rate) {
- case DESC_RATE1M...DESC_RATE5_5M:
- case DESC_RATE11M:
- break;
- case DESC_RATE6M...DESC_RATE48M:
- limit_ofdm = 36;
- break;
- case DESC_RATE54M:
- limit_ofdm = 34;
- break;
- case DESC_RATEMCS0...DESC_RATEMCS2:
- limit_ofdm = 38;
- break;
- case DESC_RATEMCS3...DESC_RATEMCS4:
- limit_ofdm = 36;
- break;
- case DESC_RATEMCS5...DESC_RATEMCS7:
- limit_ofdm = 34;
- break;
- default:
- rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate);
- break;
- }
-
- return limit_ofdm;
-}
-
static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev,
u32 ofdm_swing, u8 rf_path)
{
@@ -1845,7 +1332,7 @@ static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
s8 final_ofdm_swing_index;
s8 final_cck_swing_index;

- limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev);
+ limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev);

final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX +
dm_info->delta_power_index[path];
@@ -1873,26 +1360,6 @@ static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
}

-static void rtw8723d_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 s8 *pwrtrk_xtal;
- s8 xtal_cap;
-
- if (dm_info->thermal_avg[therm_path] >
- rtwdev->efuse.thermal_meter[therm_path])
- pwrtrk_xtal = tbl->pwrtrk_xtal_p;
- else
- pwrtrk_xtal = tbl->pwrtrk_xtal_n;
-
- xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
- xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F);
- rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
- xtal_cap | (xtal_cap << 6));
-}
-
static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
@@ -1912,7 +1379,7 @@ static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev)
do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev);

if (do_iqk)
- rtw8723d_lck(rtwdev);
+ rtw8723x_lck(rtwdev);

if (dm_info->pwr_trk_init_trigger)
dm_info->pwr_trk_init_trigger = false;
@@ -1937,7 +1404,7 @@ static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev)
rtw8723d_pwrtrack_set(rtwdev, path);
}

- rtw8723d_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta);
+ rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta);

iqk:
if (do_iqk)
@@ -1963,49 +1430,29 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
dm_info->pwr_trk_triggered = false;
}

-static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev,
- struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
-{
- size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
- __le16 chksum = 0;
- __le16 *data = (__le16 *)(txdesc);
- struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;
-
- le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM);
-
- while (words--)
- chksum ^= *data++;
-
- chksum = ~chksum;
-
- le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum),
- RTW_TX_DESC_W7_TXDESC_CHECKSUM);
-}
-
static struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
- .read_efuse = rtw8723d_read_efuse,
+ .read_efuse = rtw8723x_read_efuse,
.query_rx_desc = rtw8723d_query_rx_desc,
.set_channel = rtw8723d_set_channel,
- .mac_init = rtw8723d_mac_init,
+ .mac_init = rtw8723x_mac_init,
.shutdown = rtw8723d_shutdown,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,
- .set_tx_power_index = rtw8723d_set_tx_power_index,
+ .set_tx_power_index = rtw8723x_set_tx_power_index,
.set_antenna = NULL,
- .cfg_ldo25 = rtw8723d_cfg_ldo25,
- .efuse_grant = rtw8723d_efuse_grant,
- .false_alarm_statistics = rtw8723d_false_alarm_statistics,
+ .cfg_ldo25 = rtw8723x_cfg_ldo25,
+ .efuse_grant = rtw8723x_efuse_grant,
+ .false_alarm_statistics = rtw8723x_false_alarm_statistics,
.phy_calibration = rtw8723d_phy_calibration,
.cck_pd_set = rtw8723d_phy_cck_pd_set,
.pwr_track = rtw8723d_pwr_track,
.config_bfee = NULL,
.set_gid_table = NULL,
.cfg_csi_rate = NULL,
- .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum,
+ .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum,

- .coex_set_init = rtw8723d_coex_cfg_init,
+ .coex_set_init = rtw8723x_coex_cfg_init,
.coex_set_ant_switch = NULL,
.coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix,
.coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug,
@@ -2592,22 +2039,6 @@ static const struct rtw_rqpn rqpn_table_8723d[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};

-static const struct rtw_prioq_addrs prioq_addrs_8723d = {
- .prio[RTW_DMA_MAPPING_EXTRA] = {
- .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
- },
- .prio[RTW_DMA_MAPPING_LOW] = {
- .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
- },
- .prio[RTW_DMA_MAPPING_NORMAL] = {
- .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
- },
- .prio[RTW_DMA_MAPPING_HIGH] = {
- .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
- },
- .wsize = false,
-};
-
static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = {
{0x0008, 0x4a22,
RTW_IP_SEL_PHY,
@@ -2628,28 +2059,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_hw_reg rtw8723d_dig[] = {
- [0] = { .addr = 0xc50, .mask = 0x7f },
- [1] = { .addr = 0xc50, .mask = 0x7f },
-};
-
-static const struct rtw_hw_reg rtw8723d_dig_cck[] = {
- [0] = { .addr = 0xa0c, .mask = 0x3f00 },
-};
-
-static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = {
- [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0,
- .hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
- [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4,
- .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc},
-};
-
-static const struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = {
- .ctrl = REG_LTECOEX_CTRL,
- .wdata = REG_LTECOEX_WRITE_DATA,
- .rdata = REG_LTECOEX_READ_DATA,
-};
-
static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
[0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
.txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,},
@@ -2770,14 +2179,14 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.pwr_off_seq = card_disable_flow_8723d,
.page_table = page_table_8723d,
.rqpn_table = rqpn_table_8723d,
- .prioq_addrs = &prioq_addrs_8723d,
+ .prioq_addrs = &rtw8723x_common.prioq_addrs,
.intf_table = &phy_para_table_8723d,
- .dig = rtw8723d_dig,
- .dig_cck = rtw8723d_dig_cck,
+ .dig = rtw8723x_common.dig,
+ .dig_cck = rtw8723x_common.dig_cck,
.rf_sipi_addr = {0x840, 0x844},
- .rf_sipi_read_addr = rtw8723d_rf_sipi_addr,
+ .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr,
.fix_rf_phy_num = 2,
- .ltecoex_addr = &rtw8723d_ltecoex_addr,
+ .ltecoex_addr = &rtw8723x_common.ltecoex_addr,
.mac_tbl = &rtw8723d_mac_tbl,
.agc_tbl = &rtw8723d_agc_tbl,
.bb_tbl = &rtw8723d_bb_tbl,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
index 2434e2480cb..fba06c9f480 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
@@ -5,90 +5,7 @@
#ifndef __RTW8723D_H__
#define __RTW8723D_H__

-enum rtw8723d_path {
- PATH_S1,
- PATH_S0,
- PATH_NR,
-};
-
-enum rtw8723d_iqk_round {
- IQK_ROUND_0,
- IQK_ROUND_1,
- IQK_ROUND_2,
- IQK_ROUND_HYBRID,
- IQK_ROUND_SIZE,
- IQK_ROUND_INVALID = 0xff,
-};
-
-enum rtw8723d_iqk_result {
- IQK_S1_TX_X,
- IQK_S1_TX_Y,
- IQK_S1_RX_X,
- IQK_S1_RX_Y,
- IQK_S0_TX_X,
- IQK_S0_TX_Y,
- IQK_S0_RX_X,
- IQK_S0_RX_Y,
- IQK_NR,
- IQK_SX_NR = IQK_NR / PATH_NR,
-};
-
-struct rtw8723de_efuse {
- u8 mac_addr[ETH_ALEN]; /* 0xd0 */
- u8 vender_id[2];
- u8 device_id[2];
- u8 sub_vender_id[2];
- u8 sub_device_id[2];
-};
-
-struct rtw8723du_efuse {
- u8 res4[48]; /* 0xd0 */
- u8 vender_id[2]; /* 0x100 */
- u8 product_id[2]; /* 0x102 */
- u8 usb_option; /* 0x104 */
- u8 res5[2]; /* 0x105 */
- u8 mac_addr[ETH_ALEN]; /* 0x107 */
-};
-
-struct rtw8723ds_efuse {
- u8 res4[0x4a]; /* 0xd0 */
- u8 mac_addr[ETH_ALEN]; /* 0x11a */
-};
-
-struct rtw8723d_efuse {
- __le16 rtl_id;
- u8 rsvd[2];
- u8 afe;
- u8 rsvd1[11];
-
- /* 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[2]; /* 0xbd */
- u8 lna_type_5g[2];
- u8 rf_board_option;
- u8 rf_feature_option;
- u8 rf_bt_setting;
- u8 eeprom_version;
- u8 eeprom_customer_id;
- u8 tx_bb_swing_setting_2g;
- u8 res_c7;
- u8 tx_pwr_calibrate_rate;
- u8 rf_antenna_option; /* 0xc9 */
- u8 rfe_option;
- u8 country_code[2];
- u8 res[3];
- union {
- struct rtw8723de_efuse e;
- struct rtw8723du_efuse u;
- struct rtw8723ds_efuse s;
- };
-};
+#include "rtw8723x.h"

extern const struct rtw_chip_info rtw8723d_hw_spec;

@@ -114,193 +31,9 @@ extern const struct rtw_chip_info rtw8723d_hw_spec;
#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \
le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0))

-static inline s32 iqkxy_to_s32(s32 val)
-{
- /* val is Q10.8 */
- return sign_extend32(val, 9);
-}
-
-static inline s32 iqk_mult(s32 x, s32 y, s32 *ext)
-{
- /* x, y and return value are Q10.8 */
- s32 t;
-
- t = x * y;
- if (ext)
- *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */
-
- return (t >> 8); /* Q.16 --> Q.8 */
-}
-
-#define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing)
-#define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing)
-#define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing)
-#define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing)
#define RTW_DEF_OFDM_SWING_INDEX 28
#define RTW_DEF_CCK_SWING_INDEX 28

-#define MAX_TOLERANCE 5
-#define IQK_TX_X_ERR 0x142
-#define IQK_TX_Y_ERR 0x42
-#define IQK_RX_X_UPPER 0x11a
-#define IQK_RX_X_LOWER 0xe6
-#define IQK_RX_Y_LMT 0x1a
-#define IQK_TX_OK BIT(0)
-#define IQK_RX_OK BIT(1)
-#define PATH_IQK_RETRY 2
-
-#define SPUR_THRES 0x16
#define CCK_DFIR_NR 3
-#define DIS_3WIRE 0xccf000c0
-#define EN_3WIRE 0xccc000c0
-#define START_PSD 0x400000
-#define FREQ_CH13 0xfccd
-#define FREQ_CH14 0xff9a
-#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0)
-#define RFCFGCH_BW_MASK (BIT(11) | BIT(10))
-#define RFCFGCH_BW_20M (BIT(11) | BIT(10))
-#define RFCFGCH_BW_40M BIT(10)
-#define BIT_MASK_RFMOD BIT(0)
-#define BIT_LCK BIT(15)
-
-#define REG_GPIO_INTM 0x0048
-#define REG_BTG_SEL 0x0067
-#define BIT_MASK_BTG_WL BIT(7)
-#define REG_LTECOEX_PATH_CONTROL 0x0070
-#define REG_LTECOEX_CTRL 0x07c0
-#define REG_LTECOEX_WRITE_DATA 0x07c4
-#define REG_LTECOEX_READ_DATA 0x07c8
-#define REG_PSDFN 0x0808
-#define REG_BB_PWR_SAV1_11N 0x0874
-#define REG_ANA_PARAM1 0x0880
-#define REG_ANALOG_P4 0x088c
-#define REG_PSDRPT 0x08b4
-#define REG_FPGA1_RFMOD 0x0900
-#define REG_BB_SEL_BTG 0x0948
-#define REG_BBRX_DFIR 0x0954
-#define BIT_MASK_RXBB_DFIR GENMASK(27, 24)
-#define BIT_RXBB_DFIR_EN BIT(19)
-#define REG_CCK0_SYS 0x0a00
-#define BIT_CCK_SIDE_BAND BIT(4)
-#define REG_CCK_ANT_SEL_11N 0x0a04
-#define REG_PWRTH 0x0a08
-#define REG_CCK_FA_RST_11N 0x0a2c
-#define BIT_MASK_CCK_CNT_KEEP BIT(12)
-#define BIT_MASK_CCK_CNT_EN BIT(13)
-#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN)
-#define BIT_MASK_CCK_FA_KEEP BIT(14)
-#define BIT_MASK_CCK_FA_EN BIT(15)
-#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN)
-#define REG_CCK_FA_LSB_11N 0x0a5c
-#define REG_CCK_FA_MSB_11N 0x0a58
-#define REG_CCK_CCA_CNT_11N 0x0a60
-#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0)
-#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8)
-#define REG_PWRTH2 0x0aa8
-#define REG_CSRATIO 0x0aaa
-#define REG_OFDM_FA_HOLDC_11N 0x0c00
-#define BIT_MASK_OFDM_FA_KEEP BIT(31)
-#define REG_BB_RX_PATH_11N 0x0c04
-#define REG_TRMUX_11N 0x0c08
-#define REG_OFDM_FA_RSTC_11N 0x0c0c
-#define BIT_MASK_OFDM_FA_RST BIT(31)
-#define REG_A_RXIQI 0x0c14
-#define BIT_MASK_RXIQ_S1_X 0x000003FF
-#define BIT_MASK_RXIQ_S1_Y1 0x0000FC00
-#define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F)
-#define REG_OFDM0_RXDSP 0x0c40
-#define BIT_MASK_RXDSP GENMASK(28, 24)
-#define BIT_EN_RXDSP BIT(9)
-#define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c
-#define BIT_MASK_OFDM0_EXT_A BIT(31)
-#define BIT_MASK_OFDM0_EXT_C BIT(29)
-#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28))
-#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28))
-#define REG_OFDM0_XAAGC1 0x0c50
-#define REG_OFDM0_XBAGC1 0x0c58
-#define REG_AGCRSSI 0x0c78
-#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
-#define BIT_MASK_TXIQ_ELM_A 0x03ff
-#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \
- ((a) & 0x03ff))
-#define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16)
-#define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F)
-#define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22)
-#define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94
-#define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6)
-#define REG_RXIQK_MATRIX_LSB_11N 0x0ca0
-#define BIT_MASK_RXIQ_S1_Y2 0xF0000000
-#define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF)
-#define REG_TXIQ_AB_S0 0x0cd0
-#define BIT_MASK_TXIQ_A_S0 0x000007FE
-#define BIT_MASK_TXIQ_A_EXT_S0 BIT(0)
-#define BIT_MASK_TXIQ_B_S0 0x0007E000
-#define REG_TXIQ_CD_S0 0x0cd4
-#define BIT_MASK_TXIQ_C_S0 0x000007FE
-#define BIT_MASK_TXIQ_C_EXT_S0 BIT(0)
-#define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13)
-#define BIT_MASK_TXIQ_D_EXT_S0 BIT(12)
-#define REG_RXIQ_AB_S0 0x0cd8
-#define BIT_MASK_RXIQ_X_S0 0x000003FF
-#define BIT_MASK_RXIQ_Y_S0 0x003FF000
-#define REG_OFDM_FA_TYPE1_11N 0x0cf0
-#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0)
-#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16)
-#define REG_OFDM_FA_RSTD_11N 0x0d00
-#define BIT_MASK_OFDM_FA_RST1 BIT(27)
-#define BIT_MASK_OFDM_FA_KEEP1 BIT(31)
-#define REG_CTX 0x0d03
-#define BIT_MASK_CTX_TYPE GENMASK(6, 4)
-#define REG_OFDM1_CFOTRK 0x0d2c
-#define BIT_EN_CFOTRK BIT(28)
-#define REG_OFDM1_CSI1 0x0d40
-#define REG_OFDM1_CSI2 0x0d44
-#define REG_OFDM1_CSI3 0x0d48
-#define REG_OFDM1_CSI4 0x0d4c
-#define REG_OFDM_FA_TYPE2_11N 0x0da0
-#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0)
-#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16)
-#define REG_OFDM_FA_TYPE3_11N 0x0da4
-#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0)
-#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16)
-#define REG_OFDM_FA_TYPE4_11N 0x0da8
-#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0)
-#define REG_FPGA0_IQK_11N 0x0e28
-#define BIT_MASK_IQK_MOD 0xffffff00
-#define EN_IQK 0x808000
-#define RST_IQK 0x000000
-#define REG_TXIQK_TONE_A_11N 0x0e30
-#define REG_RXIQK_TONE_A_11N 0x0e34
-#define REG_TXIQK_PI_A_11N 0x0e38
-#define REG_RXIQK_PI_A_11N 0x0e3c
-#define REG_TXIQK_11N 0x0e40
-#define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y))
-#define REG_RXIQK_11N 0x0e44
-#define REG_IQK_AGC_PTS_11N 0x0e48
-#define REG_IQK_AGC_RSP_11N 0x0e4c
-#define REG_TX_IQK_TONE_B 0x0e50
-#define REG_RX_IQK_TONE_B 0x0e54
-#define REG_IQK_RES_TX 0x0e94
-#define BIT_MASK_RES_TX GENMASK(25, 16)
-#define REG_IQK_RES_TY 0x0e9c
-#define BIT_MASK_RES_TY GENMASK(25, 16)
-#define REG_IQK_RES_RX 0x0ea4
-#define BIT_MASK_RES_RX GENMASK(25, 16)
-#define REG_IQK_RES_RY 0x0eac
-#define BIT_IQK_TX_FAIL BIT(28)
-#define BIT_IQK_RX_FAIL BIT(27)
-#define BIT_IQK_DONE BIT(26)
-#define BIT_MASK_RES_RY GENMASK(25, 16)
-#define REG_PAGE_F_RST_11N 0x0f14
-#define BIT_MASK_F_RST_ALL BIT(16)
-#define REG_IGI_C_11N 0x0f84
-#define REG_IGI_D_11N 0x0f88
-#define REG_HT_CRC32_CNT_11N 0x0f90
-#define BIT_MASK_HT_CRC_OK GENMASK(15, 0)
-#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16)
-#define REG_OFDM_CRC32_CNT_11N 0x0f94
-#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0)
-#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16)
-#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8

#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
new file mode 100644
index 00000000000..c23650c5a20
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
@@ -0,0 +1,562 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright 2024 Fiona Klute
+ *
+ * Based on code originally in rtw8723d.[ch],
+ * Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#include "main.h"
+#include "debug.h"
+#include "phy.h"
+#include "reg.h"
+#include "tx.h"
+#include "rtw8723x.h"
+
+static const struct rtw_hw_reg rtw8723x_txagc[] = {
+ [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 },
+ [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 },
+ [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 },
+ [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 },
+ [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff },
+ [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 },
+ [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 },
+ [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 },
+ [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff },
+ [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 },
+ [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 },
+ [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 },
+ [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff },
+ [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 },
+ [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 },
+ [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 },
+ [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff },
+ [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 },
+ [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 },
+ [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 },
+};
+
+static void __rtw8723x_lck(struct rtw_dev *rtwdev)
+{
+ u32 lc_cal;
+ u8 val_ctx, rf_val;
+ int ret;
+
+ val_ctx = rtw_read8(rtwdev, REG_CTX);
+ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
+ rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE);
+ else
+ rtw_write8(rtwdev, REG_TXPAUSE, 0xFF);
+ lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK);
+
+ ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1,
+ 10000, 1000000, false,
+ rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK);
+ if (ret)
+ rtw_warn(rtwdev, "failed to poll LCK status bit\n");
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
+ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
+ rtw_write8(rtwdev, REG_CTX, val_ctx);
+ else
+ rtw_write8(rtwdev, REG_TXPAUSE, 0x00);
+}
+
+static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse,
+ struct rtw8723x_efuse *map)
+{
+ ether_addr_copy(efuse->addr, map->e.mac_addr);
+}
+
+static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse,
+ struct rtw8723x_efuse *map)
+{
+ ether_addr_copy(efuse->addr, map->u.mac_addr);
+}
+
+static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse,
+ struct rtw8723x_efuse *map)
+{
+ ether_addr_copy(efuse->addr, map->s.mac_addr);
+}
+
+static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw8723x_efuse *map;
+ int i;
+
+ map = (struct rtw8723x_efuse *)log_map;
+
+ efuse->rfe_option = 0;
+ efuse->rf_board_option = map->rf_board_option;
+ efuse->crystal_cap = map->xtal_k;
+ efuse->pa_type_2g = map->pa_type;
+ efuse->lna_type_2g = map->lna_type_2g[0];
+ 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_k = map->thermal_meter;
+ efuse->afe = map->afe;
+
+ 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_PCIE:
+ rtw8723xe_efuse_parsing(efuse, map);
+ break;
+ case RTW_HCI_TYPE_USB:
+ rtw8723xu_efuse_parsing(efuse, map);
+ break;
+ case RTW_HCI_TYPE_SDIO:
+ rtw8723xs_efuse_parsing(efuse, map);
+ break;
+ default:
+ /* unsupported now */
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+#define BIT_CFENDFORM BIT(9)
+#define BIT_WMAC_TCR_ERR0 BIT(12)
+#define BIT_WMAC_TCR_ERR1 BIT(13)
+#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \
+ BIT_WMAC_TCR_ERR1)
+#define WLAN_RX_FILTER0 0xFFFF
+#define WLAN_RX_FILTER1 0x400
+#define WLAN_RX_FILTER2 0xFFFF
+#define WLAN_RCR_CFG 0x700060CE
+
+static int __rtw8723x_mac_init(struct rtw_dev *rtwdev)
+{
+ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
+ rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);
+
+ rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
+ rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1);
+ rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
+ rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
+
+ rtw_write32(rtwdev, REG_INT_MIG, 0);
+ rtw_write32(rtwdev, REG_MCUTST_1, 0x0);
+
+ rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA);
+ rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0);
+
+ return 0;
+}
+
+static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
+{
+ u8 ldo_pwr;
+
+ ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
+ if (enable) {
+ ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE;
+ ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN;
+ } else {
+ ldo_pwr &= ~BIT_LDO25_EN;
+ }
+ rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
+}
+
+static void
+rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ const struct rtw_hw_reg *txagc;
+ u8 rate, pwr_index;
+ 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];
+
+ if (rate >= ARRAY_SIZE(rtw8723x_txagc)) {
+ rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate);
+ continue;
+ }
+ txagc = &rtw8723x_txagc[rate];
+ if (!txagc->addr) {
+ rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate);
+ continue;
+ }
+
+ rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index);
+ }
+}
+
+static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ int rs, path;
+
+ for (path = 0; path < hal->rf_path_num; path++) {
+ for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++)
+ rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs);
+ }
+}
+
+static void __rtw8723x_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 __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u32 cck_fa_cnt;
+ u32 ofdm_fa_cnt;
+ u32 crc32_cnt;
+ u32 val32;
+
+ /* hold counter */
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);
+
+ cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);
+ cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;
+
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);
+ ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);
+ dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);
+
+ dm_info->cck_fa_cnt = cck_fa_cnt;
+ dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
+ dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;
+
+ dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);
+ dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);
+ crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);
+ dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);
+ dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);
+ crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);
+ dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);
+ dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);
+ dm_info->vht_err_cnt = 0;
+ dm_info->vht_ok_cnt = 0;
+
+ val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);
+ dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |
+ u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);
+ dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;
+
+ /* reset counter */
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);
+ rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);
+ rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);
+}
+
+/* IQK (IQ calibration) */
+
+static
+void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev,
+ struct rtw8723x_iqk_backup_regs *backup)
+{
+ int i;
+
+ for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
+ backup->adda[i] = rtw_read32(rtwdev,
+ rtw8723x_common.iqk_adda_regs[i]);
+
+ for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
+ backup->mac8[i] = rtw_read8(rtwdev,
+ rtw8723x_common.iqk_mac8_regs[i]);
+ for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)
+ backup->mac32[i] = rtw_read32(rtwdev,
+ rtw8723x_common.iqk_mac32_regs[i]);
+
+ for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)
+ backup->bb[i] = rtw_read32(rtwdev,
+ rtw8723x_common.iqk_bb_regs[i]);
+
+ backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0);
+ backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0);
+
+ backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG);
+}
+
+static
+void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ int i;
+
+ for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
+ rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i],
+ backup->adda[i]);
+
+ for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
+ rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i],
+ backup->mac8[i]);
+ for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)
+ rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i],
+ backup->mac32[i]);
+
+ for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)
+ rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i],
+ backup->bb[i]);
+
+ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
+ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia);
+
+ rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50);
+ rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib);
+
+ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00);
+ rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);
+}
+
+static
+bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev,
+ s32 result[][IQK_NR],
+ u8 c1, u8 c2)
+{
+ u32 i, j, diff;
+ u32 bitmap = 0;
+ u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID};
+ bool ret = true;
+
+ s32 tmp1, tmp2;
+
+ for (i = 0; i < IQK_NR; i++) {
+ tmp1 = iqkxy_to_s32(result[c1][i]);
+ tmp2 = iqkxy_to_s32(result[c2][i]);
+
+ diff = abs(tmp1 - tmp2);
+
+ if (diff <= MAX_TOLERANCE)
+ continue;
+
+ if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) {
+ if (result[c1][i] + result[c1][i + 1] == 0)
+ candidate[i / IQK_SX_NR] = c2;
+ else if (result[c2][i] + result[c2][i + 1] == 0)
+ candidate[i / IQK_SX_NR] = c1;
+ else
+ bitmap |= BIT(i);
+ } else {
+ bitmap |= BIT(i);
+ }
+ }
+
+ if (bitmap != 0)
+ goto check_sim;
+
+ for (i = 0; i < PATH_NR; i++) {
+ if (candidate[i] == IQK_ROUND_INVALID)
+ continue;
+
+ for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++)
+ result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j];
+ ret = false;
+ }
+
+ return ret;
+
+check_sim:
+ for (i = 0; i < IQK_NR; i++) {
+ j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */
+ if (bitmap & GENMASK(j + 1, j))
+ continue;
+
+ result[IQK_ROUND_HYBRID][i] = result[c1][i];
+ }
+
+ return false;
+}
+
+static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 tx_rate = dm_info->tx_rate;
+ u8 limit_ofdm = 30;
+
+ switch (tx_rate) {
+ case DESC_RATE1M...DESC_RATE5_5M:
+ case DESC_RATE11M:
+ break;
+ case DESC_RATE6M...DESC_RATE48M:
+ limit_ofdm = 36;
+ break;
+ case DESC_RATE54M:
+ limit_ofdm = 34;
+ break;
+ case DESC_RATEMCS0...DESC_RATEMCS2:
+ limit_ofdm = 38;
+ break;
+ case DESC_RATEMCS3...DESC_RATEMCS4:
+ limit_ofdm = 36;
+ break;
+ case DESC_RATEMCS5...DESC_RATEMCS7:
+ limit_ofdm = 34;
+ break;
+ default:
+ rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate);
+ break;
+ }
+
+ return limit_ofdm;
+}
+
+static
+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 s8 *pwrtrk_xtal;
+ s8 xtal_cap;
+
+ if (dm_info->thermal_avg[therm_path] >
+ rtwdev->efuse.thermal_meter[therm_path])
+ pwrtrk_xtal = tbl->pwrtrk_xtal_p;
+ else
+ pwrtrk_xtal = tbl->pwrtrk_xtal_n;
+
+ xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
+ xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F);
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
+ xtal_cap | (xtal_cap << 6));
+}
+
+static
+void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ u8 *txdesc)
+{
+ size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
+ __le16 chksum = 0;
+ __le16 *data = (__le16 *)(txdesc);
+ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;
+
+ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM);
+
+ while (words--)
+ chksum ^= *data++;
+
+ chksum = ~chksum;
+
+ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum),
+ RTW_TX_DESC_W7_TXDESC_CHECKSUM);
+}
+
+static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev)
+{
+ /* enable TBTT nterrupt */
+ rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
+
+ /* BT report packet sample rate */
+ /* 0x790[5:0]=0x5 */
+ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
+
+ /* enable BT counter statistics */
+ rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
+
+ /* enable PTA (3-wire function form BT side) */
+ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
+ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
+
+ /* enable PTA (tx/rx signal form WiFi side) */
+ rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
+}
+
+const struct rtw8723x_common rtw8723x_common = {
+ .iqk_adda_regs = {
+ 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec
+ },
+ .iqk_mac8_regs = {0x522, 0x550, 0x551},
+ .iqk_mac32_regs = {0x40},
+ .iqk_bb_regs = {
+ 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04
+ },
+
+ .ltecoex_addr = {
+ .ctrl = REG_LTECOEX_CTRL,
+ .wdata = REG_LTECOEX_WRITE_DATA,
+ .rdata = REG_LTECOEX_READ_DATA,
+ },
+ .rf_sipi_addr = {
+ [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0,
+ .hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
+ [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4,
+ .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc},
+ },
+ .dig = {
+ [0] = { .addr = 0xc50, .mask = 0x7f },
+ [1] = { .addr = 0xc50, .mask = 0x7f },
+ },
+ .dig_cck = {
+ [0] = { .addr = 0xa0c, .mask = 0x3f00 },
+ },
+ .prioq_addrs = {
+ .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,
+ },
+
+ .lck = __rtw8723x_lck,
+ .read_efuse = __rtw8723x_read_efuse,
+ .mac_init = __rtw8723x_mac_init,
+ .cfg_ldo25 = __rtw8723x_cfg_ldo25,
+ .set_tx_power_index = __rtw8723x_set_tx_power_index,
+ .efuse_grant = __rtw8723x_efuse_grant,
+ .false_alarm_statistics = __rtw8723x_false_alarm_statistics,
+ .iqk_backup_regs = __rtw8723x_iqk_backup_regs,
+ .iqk_restore_regs = __rtw8723x_iqk_restore_regs,
+ .iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp,
+ .pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm,
+ .pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal,
+ .coex_cfg_init = __rtw8723x_coex_cfg_init,
+ .fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum,
+};
+EXPORT_SYMBOL(rtw8723x_common);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_AUTHOR("Fiona Klute <[email protected]>");
+MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
new file mode 100644
index 00000000000..cace285fc03
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
@@ -0,0 +1,496 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright 2024 Fiona Klute
+ *
+ * Based on code originally in rtw8723d.[ch],
+ * Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#ifndef __RTW8723X_H__
+#define __RTW8723X_H__
+
+#include "main.h"
+#include "debug.h"
+#include "phy.h"
+#include "reg.h"
+
+enum rtw8723x_path {
+ PATH_S1,
+ PATH_S0,
+ PATH_NR,
+};
+
+enum rtw8723x_iqk_round {
+ IQK_ROUND_0,
+ IQK_ROUND_1,
+ IQK_ROUND_2,
+ IQK_ROUND_HYBRID,
+ IQK_ROUND_SIZE,
+ IQK_ROUND_INVALID = 0xff,
+};
+
+enum rtw8723x_iqk_result {
+ IQK_S1_TX_X,
+ IQK_S1_TX_Y,
+ IQK_S1_RX_X,
+ IQK_S1_RX_Y,
+ IQK_S0_TX_X,
+ IQK_S0_TX_Y,
+ IQK_S0_RX_X,
+ IQK_S0_RX_Y,
+ IQK_NR,
+ IQK_SX_NR = IQK_NR / PATH_NR,
+};
+
+struct rtw8723xe_efuse {
+ u8 mac_addr[ETH_ALEN]; /* 0xd0 */
+ u8 vendor_id[2];
+ u8 device_id[2];
+ u8 sub_vendor_id[2];
+ u8 sub_device_id[2];
+};
+
+struct rtw8723xu_efuse {
+ u8 res4[48]; /* 0xd0 */
+ u8 vendor_id[2]; /* 0x100 */
+ u8 product_id[2]; /* 0x102 */
+ u8 usb_option; /* 0x104 */
+ u8 res5[2]; /* 0x105 */
+ u8 mac_addr[ETH_ALEN]; /* 0x107 */
+};
+
+struct rtw8723xs_efuse {
+ u8 res4[0x4a]; /* 0xd0 */
+ u8 mac_addr[ETH_ALEN]; /* 0x11a */
+};
+
+struct rtw8723x_efuse {
+ __le16 rtl_id;
+ u8 rsvd[2];
+ u8 afe;
+ u8 rsvd1[11];
+
+ /* 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[2]; /* 0xbd */
+ u8 lna_type_5g[2];
+ u8 rf_board_option;
+ u8 rf_feature_option;
+ u8 rf_bt_setting;
+ u8 eeprom_version;
+ u8 eeprom_customer_id;
+ u8 tx_bb_swing_setting_2g;
+ u8 res_c7;
+ u8 tx_pwr_calibrate_rate;
+ u8 rf_antenna_option; /* 0xc9 */
+ u8 rfe_option;
+ u8 country_code[2];
+ u8 res[3];
+ union {
+ struct rtw8723xe_efuse e;
+ struct rtw8723xu_efuse u;
+ struct rtw8723xs_efuse s;
+ };
+};
+
+#define RTW8723X_IQK_ADDA_REG_NUM 16
+#define RTW8723X_IQK_MAC8_REG_NUM 3
+#define RTW8723X_IQK_MAC32_REG_NUM 1
+#define RTW8723X_IQK_BB_REG_NUM 9
+
+struct rtw8723x_iqk_backup_regs {
+ u32 adda[RTW8723X_IQK_ADDA_REG_NUM];
+ u8 mac8[RTW8723X_IQK_MAC8_REG_NUM];
+ u32 mac32[RTW8723X_IQK_MAC32_REG_NUM];
+ u32 bb[RTW8723X_IQK_BB_REG_NUM];
+
+ u32 lte_path;
+ u32 lte_gnt;
+
+ u32 bb_sel_btg;
+ u8 btg_sel;
+
+ u8 igia;
+ u8 igib;
+};
+
+struct rtw8723x_common {
+ /* registers that must be backed up before IQK and restored after */
+ u32 iqk_adda_regs[RTW8723X_IQK_ADDA_REG_NUM];
+ u32 iqk_mac8_regs[RTW8723X_IQK_MAC8_REG_NUM];
+ u32 iqk_mac32_regs[RTW8723X_IQK_MAC32_REG_NUM];
+ u32 iqk_bb_regs[RTW8723X_IQK_BB_REG_NUM];
+
+ /* chip register definitions */
+ struct rtw_ltecoex_addr ltecoex_addr;
+ struct rtw_rf_sipi_addr rf_sipi_addr[2];
+ struct rtw_hw_reg dig[2];
+ struct rtw_hw_reg dig_cck[1];
+ struct rtw_prioq_addrs prioq_addrs;
+
+ /* common functions */
+ void (*lck)(struct rtw_dev *rtwdev);
+ int (*read_efuse)(struct rtw_dev *rtwdev, u8 *log_map);
+ int (*mac_init)(struct rtw_dev *rtwdev);
+ void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
+ void (*set_tx_power_index)(struct rtw_dev *rtwdev);
+ void (*efuse_grant)(struct rtw_dev *rtwdev, bool on);
+ void (*false_alarm_statistics)(struct rtw_dev *rtwdev);
+ void (*iqk_backup_regs)(struct rtw_dev *rtwdev,
+ struct rtw8723x_iqk_backup_regs *backup);
+ void (*iqk_restore_regs)(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup);
+ bool (*iqk_similarity_cmp)(struct rtw_dev *rtwdev, s32 result[][IQK_NR],
+ u8 c1, u8 c2);
+ u8 (*pwrtrack_get_limit_ofdm)(struct rtw_dev *rtwdev);
+ void (*pwrtrack_set_xtal)(struct rtw_dev *rtwdev, u8 therm_path,
+ u8 delta);
+ void (*coex_cfg_init)(struct rtw_dev *rtwdev);
+ void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ u8 *txdesc);
+};
+
+extern const struct rtw8723x_common rtw8723x_common;
+
+#define PATH_IQK_RETRY 2
+#define MAX_TOLERANCE 5
+#define IQK_TX_X_ERR 0x142
+#define IQK_TX_Y_ERR 0x42
+#define IQK_RX_X_UPPER 0x11a
+#define IQK_RX_X_LOWER 0xe6
+#define IQK_RX_Y_LMT 0x1a
+#define IQK_TX_OK BIT(0)
+#define IQK_RX_OK BIT(1)
+
+#define WLAN_TXQ_RPT_EN 0x1F
+
+#define SPUR_THRES 0x16
+#define DIS_3WIRE 0xccf000c0
+#define EN_3WIRE 0xccc000c0
+#define START_PSD 0x400000
+#define FREQ_CH13 0xfccd
+#define FREQ_CH14 0xff9a
+#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0)
+#define RFCFGCH_BW_MASK (BIT(11) | BIT(10))
+#define RFCFGCH_BW_20M (BIT(11) | BIT(10))
+#define RFCFGCH_BW_40M BIT(10)
+#define BIT_MASK_RFMOD BIT(0)
+#define BIT_LCK BIT(15)
+
+#define REG_GPIO_INTM 0x0048
+#define REG_BTG_SEL 0x0067
+#define BIT_MASK_BTG_WL BIT(7)
+#define REG_LTECOEX_PATH_CONTROL 0x0070
+#define REG_LTECOEX_CTRL 0x07c0
+#define REG_LTECOEX_WRITE_DATA 0x07c4
+#define REG_LTECOEX_READ_DATA 0x07c8
+#define REG_PSDFN 0x0808
+#define REG_BB_PWR_SAV1_11N 0x0874
+#define REG_ANA_PARAM1 0x0880
+#define REG_ANALOG_P4 0x088c
+#define REG_PSDRPT 0x08b4
+#define REG_FPGA1_RFMOD 0x0900
+#define REG_BB_SEL_BTG 0x0948
+#define REG_BBRX_DFIR 0x0954
+#define BIT_MASK_RXBB_DFIR GENMASK(27, 24)
+#define BIT_RXBB_DFIR_EN BIT(19)
+#define REG_CCK0_SYS 0x0a00
+#define BIT_CCK_SIDE_BAND BIT(4)
+#define REG_CCK_ANT_SEL_11N 0x0a04
+#define REG_PWRTH 0x0a08
+#define REG_CCK_FA_RST_11N 0x0a2c
+#define BIT_MASK_CCK_CNT_KEEP BIT(12)
+#define BIT_MASK_CCK_CNT_EN BIT(13)
+#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN)
+#define BIT_MASK_CCK_FA_KEEP BIT(14)
+#define BIT_MASK_CCK_FA_EN BIT(15)
+#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN)
+#define REG_CCK_FA_LSB_11N 0x0a5c
+#define REG_CCK_FA_MSB_11N 0x0a58
+#define REG_CCK_CCA_CNT_11N 0x0a60
+#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0)
+#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8)
+#define REG_PWRTH2 0x0aa8
+#define REG_CSRATIO 0x0aaa
+#define REG_OFDM_FA_HOLDC_11N 0x0c00
+#define BIT_MASK_OFDM_FA_KEEP BIT(31)
+#define REG_BB_RX_PATH_11N 0x0c04
+#define REG_TRMUX_11N 0x0c08
+#define REG_OFDM_FA_RSTC_11N 0x0c0c
+#define BIT_MASK_OFDM_FA_RST BIT(31)
+#define REG_A_RXIQI 0x0c14
+#define BIT_MASK_RXIQ_S1_X 0x000003FF
+#define BIT_MASK_RXIQ_S1_Y1 0x0000FC00
+#define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F)
+#define REG_OFDM0_RXDSP 0x0c40
+#define BIT_MASK_RXDSP GENMASK(28, 24)
+#define BIT_EN_RXDSP BIT(9)
+#define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c
+#define BIT_MASK_OFDM0_EXT_A BIT(31)
+#define BIT_MASK_OFDM0_EXT_C BIT(29)
+#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28))
+#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28))
+#define REG_OFDM0_XAAGC1 0x0c50
+#define REG_OFDM0_XBAGC1 0x0c58
+#define REG_AGCRSSI 0x0c78
+#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
+#define BIT_MASK_TXIQ_ELM_A 0x03ff
+#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \
+ ((a) & 0x03ff))
+#define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16)
+#define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F)
+#define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22)
+#define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94
+#define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6)
+#define REG_RXIQK_MATRIX_LSB_11N 0x0ca0
+#define BIT_MASK_RXIQ_S1_Y2 0xF0000000
+#define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF)
+#define REG_TXIQ_AB_S0 0x0cd0
+#define BIT_MASK_TXIQ_A_S0 0x000007FE
+#define BIT_MASK_TXIQ_A_EXT_S0 BIT(0)
+#define BIT_MASK_TXIQ_B_S0 0x0007E000
+#define REG_TXIQ_CD_S0 0x0cd4
+#define BIT_MASK_TXIQ_C_S0 0x000007FE
+#define BIT_MASK_TXIQ_C_EXT_S0 BIT(0)
+#define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13)
+#define BIT_MASK_TXIQ_D_EXT_S0 BIT(12)
+#define REG_RXIQ_AB_S0 0x0cd8
+#define BIT_MASK_RXIQ_X_S0 0x000003FF
+#define BIT_MASK_RXIQ_Y_S0 0x003FF000
+#define REG_OFDM_FA_TYPE1_11N 0x0cf0
+#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0)
+#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16)
+#define REG_OFDM_FA_RSTD_11N 0x0d00
+#define BIT_MASK_OFDM_FA_RST1 BIT(27)
+#define BIT_MASK_OFDM_FA_KEEP1 BIT(31)
+#define REG_CTX 0x0d03
+#define BIT_MASK_CTX_TYPE GENMASK(6, 4)
+#define REG_OFDM1_CFOTRK 0x0d2c
+#define BIT_EN_CFOTRK BIT(28)
+#define REG_OFDM1_CSI1 0x0d40
+#define REG_OFDM1_CSI2 0x0d44
+#define REG_OFDM1_CSI3 0x0d48
+#define REG_OFDM1_CSI4 0x0d4c
+#define REG_OFDM_FA_TYPE2_11N 0x0da0
+#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0)
+#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16)
+#define REG_OFDM_FA_TYPE3_11N 0x0da4
+#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0)
+#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16)
+#define REG_OFDM_FA_TYPE4_11N 0x0da8
+#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0)
+#define REG_FPGA0_IQK_11N 0x0e28
+#define BIT_MASK_IQK_MOD 0xffffff00
+#define EN_IQK 0x808000
+#define RST_IQK 0x000000
+#define REG_TXIQK_TONE_A_11N 0x0e30
+#define REG_RXIQK_TONE_A_11N 0x0e34
+#define REG_TXIQK_PI_A_11N 0x0e38
+#define REG_RXIQK_PI_A_11N 0x0e3c
+#define REG_TXIQK_11N 0x0e40
+#define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y))
+#define REG_RXIQK_11N 0x0e44
+#define REG_IQK_AGC_PTS_11N 0x0e48
+#define REG_IQK_AGC_RSP_11N 0x0e4c
+#define REG_TX_IQK_TONE_B 0x0e50
+#define REG_RX_IQK_TONE_B 0x0e54
+#define REG_IQK_RES_TX 0x0e94
+#define BIT_MASK_RES_TX GENMASK(25, 16)
+#define REG_IQK_RES_TY 0x0e9c
+#define BIT_MASK_RES_TY GENMASK(25, 16)
+#define REG_IQK_RES_RX 0x0ea4
+#define BIT_MASK_RES_RX GENMASK(25, 16)
+#define REG_IQK_RES_RY 0x0eac
+#define BIT_IQK_TX_FAIL BIT(28)
+#define BIT_IQK_RX_FAIL BIT(27)
+#define BIT_IQK_DONE BIT(26)
+#define BIT_MASK_RES_RY GENMASK(25, 16)
+#define REG_PAGE_F_RST_11N 0x0f14
+#define BIT_MASK_F_RST_ALL BIT(16)
+#define REG_IGI_C_11N 0x0f84
+#define REG_IGI_D_11N 0x0f88
+#define REG_HT_CRC32_CNT_11N 0x0f90
+#define BIT_MASK_HT_CRC_OK GENMASK(15, 0)
+#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16)
+#define REG_OFDM_CRC32_CNT_11N 0x0f94
+#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0)
+#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16)
+#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8
+
+#define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing)
+#define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing)
+#define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing)
+#define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing)
+
+static inline s32 iqkxy_to_s32(s32 val)
+{
+ /* val is Q10.8 */
+ return sign_extend32(val, 9);
+}
+
+static inline s32 iqk_mult(s32 x, s32 y, s32 *ext)
+{
+ /* x, y and return value are Q10.8 */
+ s32 t;
+
+ t = x * y;
+ if (ext)
+ *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */
+
+ return (t >> 8); /* Q.16 --> Q.8 */
+}
+
+static inline void rtw8723x_lck(struct rtw_dev *rtwdev)
+{
+ rtw8723x_common.lck(rtwdev);
+}
+
+static inline int rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+ return rtw8723x_common.read_efuse(rtwdev, log_map);
+}
+
+static inline int rtw8723x_mac_init(struct rtw_dev *rtwdev)
+{
+ return rtw8723x_common.mac_init(rtwdev);
+}
+
+static inline void rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
+{
+ rtw8723x_common.cfg_ldo25(rtwdev, enable);
+}
+
+static inline void rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev)
+{
+ rtw8723x_common.set_tx_power_index(rtwdev);
+}
+
+static inline void rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on)
+{
+ rtw8723x_common.efuse_grant(rtwdev, on);
+}
+
+static inline void rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev)
+{
+ rtw8723x_common.false_alarm_statistics(rtwdev);
+}
+
+static inline
+void rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev,
+ struct rtw8723x_iqk_backup_regs *backup)
+{
+ rtw8723x_common.iqk_backup_regs(rtwdev, backup);
+}
+
+static inline
+void rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ rtw8723x_common.iqk_restore_regs(rtwdev, backup);
+}
+
+static inline
+bool rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR],
+ u8 c1, u8 c2)
+{
+ return rtw8723x_common.iqk_similarity_cmp(rtwdev, result, c1, c2);
+}
+
+static inline u8 rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)
+{
+ return rtw8723x_common.pwrtrack_get_limit_ofdm(rtwdev);
+}
+
+static inline
+void rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
+ u8 delta)
+{
+ rtw8723x_common.pwrtrack_set_xtal(rtwdev, therm_path, delta);
+}
+
+static inline void rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev)
+{
+ rtw8723x_common.coex_cfg_init(rtwdev);
+}
+
+static inline
+void rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ u8 *txdesc)
+{
+ rtw8723x_common.fill_txdesc_checksum(rtwdev, pkt_info, txdesc);
+}
+
+/* IQK helper functions, defined as inline so they can be shared
+ * without needing an EXPORT_SYMBOL each.
+ */
+static inline void
+rtw8723x_iqk_backup_path_ctrl(struct rtw_dev *rtwdev,
+ struct rtw8723x_iqk_backup_regs *backup)
+{
+ backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n",
+ backup->btg_sel);
+}
+
+static inline void rtw8723x_iqk_config_path_ctrl(struct rtw_dev *rtwdev)
+{
+ rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n",
+ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
+}
+
+static inline void
+rtw8723x_iqk_restore_path_ctrl(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n",
+ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
+}
+
+static inline void
+rtw8723x_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev,
+ struct rtw8723x_iqk_backup_regs *backup)
+{
+ backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL);
+ rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038);
+ mdelay(1);
+ backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA);
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n",
+ backup->lte_gnt);
+}
+
+static inline void
+rtw8723x_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev,
+ u32 write_data)
+{
+ rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, write_data);
+ rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038);
+ rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL,
+ BIT_LTE_MUX_CTRL_PATH, 0x1);
+}
+
+static inline void
+rtw8723x_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *bak)
+{
+ rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt);
+ rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038);
+ rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path);
+}
+
+/* set all ADDA registers to the given value */
+static inline void rtw8723x_iqk_path_adda_on(struct rtw_dev *rtwdev, u32 value)
+{
+ for (int i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
+ rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], value);
+}
+
+#endif /* __RTW8723X_H__ */
--
2.43.0


2024-03-12 02:59:14

by Ping-Ke Shih

[permalink] [raw]
Subject: RE: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B


> v4:
> * Move definition of GET_RX_DESC_BW from rtw8703b.c to rx.h (now in
> patch 3/9 "wifi: rtw88: Add definitions for 8703b chip")

v4 looks good to me. Thanks for the great work!

I also have run sparse/smatch with v4, no warning/error.

Ping-Ke

2024-03-12 08:43:21

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B

Hi!

> > v4:
> > * Move definition of GET_RX_DESC_BW from rtw8703b.c to rx.h (now in
> > patch 3/9 "wifi: rtw88: Add definitions for 8703b chip")
>
> v4 looks good to me. Thanks for the great work!
>
> I also have run sparse/smatch with v4, no warning/error.

Does it mean you queued the patch, or is someone else expected to do
that?

Best regards,
Pavel
--
People of Russia, stop Putin before his war on Ukraine escalates.


Attachments:
(No filename) (460.00 B)
signature.asc (201.00 B)
Download all attachments

2024-03-12 09:00:56

by Ping-Ke Shih

[permalink] [raw]
Subject: Re: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B

On Tue, 2024-03-12 at 09:43 +0100, Pavel Machek wrote:
> Hi!
>
> > > v4:
> > > * Move definition of GET_RX_DESC_BW from rtw8703b.c to rx.h (now in
> > > patch 3/9 "wifi: rtw88: Add definitions for 8703b chip")
> >
> > v4 looks good to me. Thanks for the great work!
> >
> > I also have run sparse/smatch with v4, no warning/error.
>
> Does it mean you queued the patch, or is someone else expected to do
> that?
>

I mean this patchset is okay to me, and Kalle will help to apply this
patchset to wireless-next tree. I suppose next next kernel v6.10 will
have this.

Ping-Ke




2024-03-12 16:09:40

by Larry Finger

[permalink] [raw]
Subject: Re: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B

Those patches have been merged with
https://github.com/lwfinger/rtw88.git. If you have an rtw8723ds, you
can access the new driver now.

On Tue, Mar 12, 2024 at 4:01 AM Ping-Ke Shih <[email protected]> wrote:
>
> On Tue, 2024-03-12 at 09:43 +0100, Pavel Machek wrote:
> > Hi!
> >
> > > > v4:
> > > > * Move definition of GET_RX_DESC_BW from rtw8703b.c to rx.h (now in
> > > > patch 3/9 "wifi: rtw88: Add definitions for 8703b chip")
> > >
> > > v4 looks good to me. Thanks for the great work!
> > >
> > > I also have run sparse/smatch with v4, no warning/error.
> >
> > Does it mean you queued the patch, or is someone else expected to do
> > that?
> >
>
> I mean this patchset is okay to me, and Kalle will help to apply this
> patchset to wireless-next tree. I suppose next next kernel v6.10 will
> have this.
>
> Ping-Ke
>
>
>
>

2024-03-13 13:15:55

by Fiona Klute

[permalink] [raw]
Subject: Re: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B

Am 12.03.24 um 10:00 schrieb Ping-Ke Shih:
> On Tue, 2024-03-12 at 09:43 +0100, Pavel Machek wrote:
>> Hi!
>>
>>>> v4:
>>>> * Move definition of GET_RX_DESC_BW from rtw8703b.c to rx.h (now in
>>>> patch 3/9 "wifi: rtw88: Add definitions for 8703b chip")
>>>
>>> v4 looks good to me. Thanks for the great work!
>>>
>>> I also have run sparse/smatch with v4, no warning/error.
>>
>> Does it mean you queued the patch, or is someone else expected to do
>> that?
>>
>
> I mean this patchset is okay to me, and Kalle will help to apply this
> patchset to wireless-next tree. I suppose next next kernel v6.10 will
> have this.

Thanks, you two asked and answered the question I would've asked
already. :-)

Is there anything I still need to do to get the firmware into
linux-firmware?

Best regards,
Fiona


2024-03-14 00:19:24

by Ping-Ke Shih

[permalink] [raw]
Subject: Re: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B


>
> Is there anything I still need to do to get the firmware into
> linux-firmware?
>

Please send me a firmware patch again. In case I send wrong firmware to
liunx-firmware.

Ping-Ke

2024-03-14 09:00:25

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v4 1/9] wifi: rtw88: Shared module for rtw8723x devices

Fiona Klute <[email protected]> wrote:

> The already supported 8723d chip is very similar to 8703b/8723cs,
> split code that can be shared into a new module. The spec definition
> tables are combined into a struct so we only need one EXPORT_SYMBOL
> for them all.
>
> Acked-by: Ping-Ke Shih <[email protected]>
> Tested-by: Pavel Machek <[email protected]>
> Signed-off-by: Fiona Klute <[email protected]>

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

ff88b7488266 wifi: rtw88: Shared module for rtw8723x devices
da2abdcdbbb8 wifi: rtw88: Debug output for rtw8723x EFUSE
9bb762b3a957 wifi: rtw88: Add definitions for 8703b chip
23c21068c296 wifi: rtw88: Add rtw8703b.h
61a486bcd782 wifi: rtw88: Add rtw8703b.c
b0ec946c543b wifi: rtw88: Add rtw8703b_tables.h
c75065b1ebfc wifi: rtw88: Add rtw8703b_tables.c
1f30e95b1646 wifi: rtw88: Reset 8703b firmware before download
64be03575f9e wifi: rtw88: SDIO device driver for RTL8723CS

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

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


2024-03-14 09:02:33

by Fiona Klute

[permalink] [raw]
Subject: Re: [PATCH v4 0/9] rtw88: Add support for RTL8723CS/RTL8703B

Am 14.03.24 um 01:18 schrieb Ping-Ke Shih:
>
>>
>> Is there anything I still need to do to get the firmware into
>> linux-firmware?
>>
>
> Please send me a firmware patch again. In case I send wrong firmware to
> liunx-firmware.

I've just sent it. Thanks for taking care of this!

Fiona



2024-03-11 10:39:44

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 5/9] wifi: rtw88: Add rtw8703b.c

This is the main source for the new rtw88_8703b chip driver.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2109 +++++++++++++++++
1 file changed, 2109 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.c

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
new file mode 100644
index 00000000000..8919f9e11f0
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -0,0 +1,2109 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright Fiona Klute <[email protected]> */
+
+#include <linux/of_net.h>
+#include "main.h"
+#include "coex.h"
+#include "debug.h"
+#include "mac.h"
+#include "phy.h"
+#include "reg.h"
+#include "rx.h"
+#include "rtw8703b.h"
+#include "rtw8703b_tables.h"
+#include "rtw8723x.h"
+
+#define BIT_MASK_TXQ_INIT (BIT(7))
+#define WLAN_RL_VAL 0x3030
+/* disable BAR */
+#define WLAN_BAR_VAL 0x0201ffff
+#define WLAN_PIFS_VAL 0
+#define WLAN_RX_PKT_LIMIT 0x18
+#define WLAN_SLOT_TIME 0x09
+#define WLAN_SPEC_SIFS 0x100a
+#define WLAN_MAX_AGG_NR 0x1f
+#define WLAN_AMPDU_MAX_TIME 0x70
+
+/* unit is 32us */
+#define TBTT_PROHIBIT_SETUP_TIME 0x04
+#define TBTT_PROHIBIT_HOLD_TIME 0x80
+#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64
+
+/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */
+#define RX_DRV_INFO_SZ_UNIT_8703B 8
+
+#define TRANS_SEQ_END \
+ 0xFFFF, \
+ RTW_PWR_CUT_ALL_MSK, \
+ RTW_PWR_INTF_ALL_MSK, \
+ 0, \
+ RTW_PWR_CMD_END, 0, 0
+
+/* rssi in percentage % (dbm = % - 100) */
+/* These are used to select simple signal quality levels, might need
+ * tweaking. Same for rf_para tables below.
+ */
+static const u8 wl_rssi_step_8703b[] = {60, 50, 44, 30};
+static const u8 bt_rssi_step_8703b[] = {30, 30, 30, 30};
+static const struct coex_5g_afh_map afh_5g_8703b[] = { {0, 0, 0} };
+
+/* Actually decreasing wifi TX power/RX gain isn't implemented in
+ * rtw8703b, but hopefully adjusting the BT side helps.
+ */
+static const struct coex_rf_para rf_para_tx_8703b[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 10, false, 7}, /* for WL-CPT */
+ {1, 0, true, 4},
+ {1, 2, true, 4},
+ {1, 10, true, 4},
+ {1, 15, true, 4}
+};
+
+static const struct coex_rf_para rf_para_rx_8703b[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 10, false, 7}, /* for WL-CPT */
+ {1, 0, true, 5},
+ {1, 2, true, 5},
+ {1, 10, true, 5},
+ {1, 15, true, 5}
+};
+
+static const u32 rtw8703b_ofdm_swing_table[] = {
+ 0x0b40002d, /* 0, -15.0dB */
+ 0x0c000030, /* 1, -14.5dB */
+ 0x0cc00033, /* 2, -14.0dB */
+ 0x0d800036, /* 3, -13.5dB */
+ 0x0e400039, /* 4, -13.0dB */
+ 0x0f00003c, /* 5, -12.5dB */
+ 0x10000040, /* 6, -12.0dB */
+ 0x11000044, /* 7, -11.5dB */
+ 0x12000048, /* 8, -11.0dB */
+ 0x1300004c, /* 9, -10.5dB */
+ 0x14400051, /* 10, -10.0dB */
+ 0x15800056, /* 11, -9.5dB */
+ 0x16c0005b, /* 12, -9.0dB */
+ 0x18000060, /* 13, -8.5dB */
+ 0x19800066, /* 14, -8.0dB */
+ 0x1b00006c, /* 15, -7.5dB */
+ 0x1c800072, /* 16, -7.0dB */
+ 0x1e400079, /* 17, -6.5dB */
+ 0x20000080, /* 18, -6.0dB */
+ 0x22000088, /* 19, -5.5dB */
+ 0x24000090, /* 20, -5.0dB */
+ 0x26000098, /* 21, -4.5dB */
+ 0x288000a2, /* 22, -4.0dB */
+ 0x2ac000ab, /* 23, -3.5dB */
+ 0x2d4000b5, /* 24, -3.0dB */
+ 0x300000c0, /* 25, -2.5dB */
+ 0x32c000cb, /* 26, -2.0dB */
+ 0x35c000d7, /* 27, -1.5dB */
+ 0x390000e4, /* 28, -1.0dB */
+ 0x3c8000f2, /* 29, -0.5dB */
+ 0x40000100, /* 30, +0dB */
+ 0x43c0010f, /* 31, +0.5dB */
+ 0x47c0011f, /* 32, +1.0dB */
+ 0x4c000130, /* 33, +1.5dB */
+ 0x50800142, /* 34, +2.0dB */
+ 0x55400155, /* 35, +2.5dB */
+ 0x5a400169, /* 36, +3.0dB */
+ 0x5fc0017f, /* 37, +3.5dB */
+ 0x65400195, /* 38, +4.0dB */
+ 0x6b8001ae, /* 39, +4.5dB */
+ 0x71c001c7, /* 40, +5.0dB */
+ 0x788001e2, /* 41, +5.5dB */
+ 0x7f8001fe /* 42, +6.0dB */
+};
+
+static const u32 rtw8703b_cck_pwr_regs[] = {
+ 0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 0x0a28, 0x0a29,
+ 0x0a9a, 0x0a9b, 0x0a9c, 0x0a9d, 0x0aa0, 0x0aa1, 0x0aa2, 0x0aa3,
+};
+
+static const u8 rtw8703b_cck_swing_table[][16] = {
+ {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
+ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
+ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
+ {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
+};
+
+#define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_ofdm_swing_table)
+#define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_cck_swing_table)
+
+static const struct rtw_pwr_seq_cmd trans_pre_enable_8703b[] = {
+ /* set up external crystal (XTAL) */
+ {REG_PAD_CTRL1 + 2,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
+ /* set CLK_REQ to high active */
+ {0x0069,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ /* unlock ISO/CLK/power control register */
+ {REG_RSV_CTRL,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xff, 0},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8703b[] = {
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7), 0},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8703b[] = {
+ {0x0023,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
+ {0x0007,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK | RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x20},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_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(7), BIT(7)},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8703b[] = {
+ {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)},
+ {0x0004,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
+ {0x0004,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), 0},
+ /* wait for power ready */
+ {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},
+ {0x0010,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
+ {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)},
+ {0x0068,
+ RTW_PWR_CUT_TEST_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
+ {0x0069,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8703b[] = {
+ {0x001f,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xff, 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_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(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},
+ {0x0010,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(6), 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},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_reset_mcu_8703b[] = {
+ {REG_SYS_FUNC_EN + 1,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT_FEN_CPUEN, 0},
+ /* reset MCU ready */
+ {REG_MCUFW_CTRL,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xff, 0},
+ /* reset MCU IO wrapper */
+ {REG_RSV_CTRL + 1,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {REG_RSV_CTRL + 1,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 1},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = {
+ {0x0301,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_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, 0},
+ {0x0553,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ {TRANS_SEQ_END},
+};
+
+static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = {
+ trans_pre_enable_8703b,
+ trans_carddis_to_cardemu_8703b,
+ trans_cardemu_to_act_8703b,
+ NULL
+};
+
+static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {
+ trans_act_to_lps_8703b,
+ trans_act_to_reset_mcu_8703b,
+ trans_act_to_cardemu_8703b,
+ trans_cardemu_to_carddis_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},
+ {12, 2, 2, 0, 1},
+ {12, 2, 2, 0, 1},
+ {12, 2, 2, 0, 1},
+};
+
+static const struct rtw_rqpn rqpn_table_8703b[] = {
+ {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_NORMAL, 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_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},
+};
+
+/* Default power index table for RTL8703B, used if EFUSE does not
+ * contain valid data. Replaces EFUSE data from offset 0x10 (start of
+ * txpwr_idx_table).
+ */
+static const u8 rtw8703b_txpwr_idx_table[] = {
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02
+};
+
+static void try_mac_from_devicetree(struct rtw_dev *rtwdev)
+{
+ struct device_node *node = rtwdev->dev->of_node;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ int ret;
+
+ if (node) {
+ ret = of_get_mac_address(node, efuse->addr);
+ if (ret == 0) {
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "got wifi mac address from DT: %pM\n",
+ efuse->addr);
+ }
+ }
+}
+
+#define DBG_EFUSE_FIX(rtwdev, name) \
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: " \
+ # name "=0x%x\n", rtwdev->efuse.name)
+
+static int rtw8703b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ u8 *pwr = (u8 *)efuse->txpwr_idx_table;
+ bool valid = false;
+ int ret;
+
+ ret = rtw8723x_read_efuse(rtwdev, log_map);
+ if (ret != 0)
+ return ret;
+
+ if (!is_valid_ether_addr(efuse->addr))
+ try_mac_from_devicetree(rtwdev);
+
+ /* If TX power index table in EFUSE is invalid, fall back to
+ * built-in table.
+ */
+ for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++)
+ if (pwr[i] != 0xff) {
+ valid = true;
+ break;
+ }
+ if (!valid) {
+ for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++)
+ pwr[i] = rtw8703b_txpwr_idx_table[i];
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "Replaced invalid EFUSE TX power index table.");
+ rtw8723x_debug_txpwr_limit(rtwdev,
+ efuse->txpwr_idx_table, 2);
+ }
+
+ /* Override invalid antenna settings. */
+ if (efuse->bt_setting == 0xff) {
+ /* shared antenna */
+ efuse->bt_setting |= BIT(0);
+ /* RF path A */
+ efuse->bt_setting &= ~BIT(6);
+ DBG_EFUSE_FIX(rtwdev, bt_setting);
+ }
+
+ /* Override invalid board options: The coex code incorrectly
+ * assumes that if bits 6 & 7 are set the board doesn't
+ * support coex. Regd is also derived from rf_board_option and
+ * should be 0 if there's no valid data.
+ */
+ if (efuse->rf_board_option == 0xff) {
+ efuse->regd = 0;
+ efuse->rf_board_option &= GENMASK(5, 0);
+ DBG_EFUSE_FIX(rtwdev, rf_board_option);
+ }
+
+ /* Override invalid crystal cap setting, default comes from
+ * vendor driver. Chip specific.
+ */
+ if (efuse->crystal_cap == 0xff) {
+ efuse->crystal_cap = 0x20;
+ DBG_EFUSE_FIX(rtwdev, crystal_cap);
+ }
+
+ return 0;
+}
+
+static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 path;
+
+ /* TODO: The vendor driver selects these using tables in
+ * halrf_powertracking_ce.c, functions are called
+ * get_swing_index and get_cck_swing_index. There the current
+ * fixed values are only the defaults in case no match is
+ * found.
+ */
+ dm_info->default_ofdm_index = 30;
+ dm_info->default_cck_index = 20;
+
+ 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->pwr_trk_triggered = false;
+ 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;
+}
+
+static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev)
+{
+ u8 xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
+
+ /* power on BB/RF domain */
+ rtw_write16_set(rtwdev, REG_SYS_FUNC_EN,
+ BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB);
+ rtw_write8_set(rtwdev, REG_RF_CTRL,
+ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780);
+ rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80);
+
+ rtw_phy_load_tables(rtwdev);
+
+ rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF);
+ /* 0xff is from vendor driver, rtw8723d uses
+ * BIT_HIQ_NO_LMT_EN_ROOT. Comment in vendor driver: "Packet
+ * in Hi Queue Tx immediately". I wonder if setting all bits
+ * is really necessary.
+ */
+ rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, 0xff);
+ rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN);
+
+ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
+ xtal_cap | (xtal_cap << 6));
+ rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN);
+
+ /* Init EDCA */
+ rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SPEC_SIFS);
+ rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS);
+ rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); /* CCK */
+ rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); /* OFDM */
+ /* TXOP */
+ rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226);
+ rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324);
+ rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B);
+ rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F);
+
+ /* Init retry */
+ rtw_write8(rtwdev, REG_ACKTO, 0x40);
+
+ /* Set up RX aggregation. sdio.c also sets DMA mode, but not
+ * the burst parameters.
+ */
+ rtw_write8(rtwdev, REG_RXDMA_MODE,
+ BIT_DMA_MODE |
+ FIELD_PREP_CONST(BIT_MASK_AGG_BURST_NUM, AGG_BURST_NUM) |
+ FIELD_PREP_CONST(BIT_MASK_AGG_BURST_SIZE, AGG_BURST_SIZE));
+
+ /* Init beacon parameters */
+ rtw_write8(rtwdev, REG_BCN_CTRL,
+ BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT);
+ rtw_write8(rtwdev, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
+ rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1,
+ TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
+ rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2,
+ (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) & 0xF0)
+ | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
+
+ /* configure packet burst */
+ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU);
+ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT);
+ rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR);
+ rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL);
+ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT_MASK_TXQ_INIT);
+ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME);
+
+ rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
+ rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL);
+ rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL);
+ rtw_write16(rtwdev, REG_ATIMWND, 0x2);
+
+ rtw_phy_init(rtwdev);
+
+ if (rtw_read32_mask(rtwdev, REG_BB_AMP, BIT_MASK_RX_LNA) != 0) {
+ rtwdev->dm_info.rx_cck_agc_report_type = 1;
+ } else {
+ rtwdev->dm_info.rx_cck_agc_report_type = 0;
+ rtw_warn(rtwdev, "unexpected cck agc report type");
+ }
+
+ rtw8723x_lck(rtwdev);
+
+ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
+ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20);
+
+ rtw8703b_pwrtrack_init(rtwdev);
+}
+
+static bool rtw8703b_check_spur_ov_thres(struct rtw_dev *rtwdev,
+ u32 freq, u32 thres)
+{
+ bool ret = false;
+
+ rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE);
+ rtw_write32(rtwdev, REG_PSDFN, freq);
+ rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq);
+
+ msleep(30);
+ if (rtw_read32(rtwdev, REG_PSDRPT) >= thres)
+ ret = true;
+
+ rtw_write32(rtwdev, REG_PSDFN, freq);
+ rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE);
+
+ return ret;
+}
+
+static void rtw8703b_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch)
+{
+ if (!notch) {
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
+ return;
+ }
+
+ switch (channel) {
+ case 5:
+ fallthrough;
+ case 13:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x06000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ case 6:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x4);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000600);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ case 7:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x3);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x06000000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ case 8:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xa);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000380);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ case 14:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00180000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ default:
+ rtw_warn(rtwdev,
+ "Bug: Notch filter enable called for channel %u!",
+ channel);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
+ break;
+ }
+}
+
+static void rtw8703b_spur_cal(struct rtw_dev *rtwdev, u8 channel)
+{
+ bool notch;
+ u32 freq;
+
+ if (channel == 5) {
+ freq = FREQ_CH5;
+ } else if (channel == 6) {
+ freq = FREQ_CH6;
+ } else if (channel == 7) {
+ freq = FREQ_CH7;
+ } else if (channel == 8) {
+ freq = FREQ_CH8;
+ } else if (channel == 13) {
+ freq = FREQ_CH13;
+ } else if (channel == 14) {
+ freq = FREQ_CH14;
+ } else {
+ rtw8703b_cfg_notch(rtwdev, channel, false);
+ return;
+ }
+
+ notch = rtw8703b_check_spur_ov_thres(rtwdev, freq, SPUR_THRES);
+ rtw8703b_cfg_notch(rtwdev, channel, notch);
+}
+
+static void rtw8703b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+ u32 rf_cfgch_a;
+ u32 rf_cfgch_b;
+ /* default value for 20M */
+ u32 rf_rck = 0x00000C08;
+
+ rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
+ rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK);
+
+ rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK;
+ rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK;
+ rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK);
+ rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK);
+
+ rf_cfgch_a &= ~RFCFGCH_BW_MASK;
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_20:
+ rf_cfgch_a |= RFCFGCH_BW_20M;
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rf_cfgch_a |= RFCFGCH_BW_40M;
+ rf_rck = 0x00000C4C;
+ break;
+ default:
+ break;
+ }
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK, rf_rck);
+ rtw8703b_spur_cal(rtwdev, channel);
+}
+
+#define CCK_DFIR_NR_8703B 2
+static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR_8703B] = {
+ [0] = {
+ { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x5A7DA0BD },
+ { .len = 4, .reg = REG_CCK_DBG, .val = 0x0000223B },
+ },
+ [1] = {
+ { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x00000000 },
+ { .len = 4, .reg = REG_CCK_DBG, .val = 0x00000000 },
+ },
+};
+
+static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_ch_idx)
+{
+ const struct rtw_backup_info *cck_dfir;
+ int i;
+
+ cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1];
+
+ for (i = 0; i < CCK_DFIR_NR_8703B; i++, cck_dfir++)
+ rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val);
+
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_20:
+ rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0);
+ rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0);
+ rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE,
+ GENMASK(31, 20), 0x0);
+ rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000);
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000);
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1);
+ rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1);
+ rtw_write32(rtwdev, REG_BBRX_DFIR, 0x40100000);
+ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x51F60000);
+ rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND,
+ primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, 0xC00,
+ primary_ch_idx == RTW_SC_20_UPPER ? 2 : 1);
+
+ rtw_write32_mask(rtwdev, REG_BB_PWR_SAV5_11N, GENMASK(27, 26),
+ primary_ch_idx == RTW_SC_20_UPPER ? 1 : 2);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rtw8703b_set_channel(struct rtw_dev *rtwdev, u8 channel,
+ u8 bw, u8 primary_chan_idx)
+{
+ rtw8703b_set_channel_rf(rtwdev, channel, bw);
+ rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
+ rtw8703b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
+}
+
+/* Not all indices are valid, based on available data. None of the
+ * known valid values are positive, so use 0x7f as "invalid".
+ */
+#define LNA_IDX_INVALID 0x7f
+static const s8 lna_gain_table[16] = {
+ -2, LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID,
+ -6, LNA_IDX_INVALID, LNA_IDX_INVALID, -19,
+ -32, LNA_IDX_INVALID, -36, -42,
+ LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, -48,
+};
+
+static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx)
+{
+ s8 lna_gain = 0;
+
+ if (lna_idx < ARRAY_SIZE(lna_gain_table))
+ lna_gain = lna_gain_table[lna_idx];
+
+ if (lna_gain >= 0) {
+ rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx);
+ return -120;
+ }
+
+ return lna_gain - 2 * vga_idx;
+}
+
+static void query_phy_status_cck(struct rtw_dev *rtwdev, u8 *phy_raw,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw;
+ u8 vga_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & VGA_BITS;
+ u8 lna_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & LNA_L_BITS;
+ s8 rx_power;
+
+ if (rtwdev->dm_info.rx_cck_agc_report_type == 1)
+ lna_idx = FIELD_PREP(BIT_LNA_H_MASK,
+ phy_status->cck_rpt_b_ofdm_cfosho_b & LNA_H_BIT)
+ | FIELD_PREP(BIT_LNA_L_MASK, lna_idx);
+ else
+ lna_idx = FIELD_PREP(BIT_LNA_L_MASK, lna_idx);
+ rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
+
+ pkt_stat->rx_power[RF_PATH_A] = rx_power;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ rtwdev->dm_info.rssi[RF_PATH_A] = pkt_stat->rssi;
+ pkt_stat->signal_power = rx_power;
+}
+
+static void query_phy_status_ofdm(struct rtw_dev *rtwdev, u8 *phy_raw,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw;
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ s8 val_s8;
+
+ val_s8 = phy_status->path_agc[RF_PATH_A].gain & 0x3F;
+ pkt_stat->rx_power[RF_PATH_A] = (val_s8 * 2) - 110;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ pkt_stat->rx_snr[RF_PATH_A] = (s8)(phy_status->path_rxsnr[RF_PATH_A] / 2);
+
+ /* signal power reported by HW */
+ val_s8 = phy_status->cck_sig_qual_ofdm_pwdb_all >> 1;
+ pkt_stat->signal_power = (val_s8 & 0x7f) - 110;
+
+ pkt_stat->rx_evm[RF_PATH_A] = phy_status->stream_rxevm[RF_PATH_A];
+ pkt_stat->cfo_tail[RF_PATH_A] = phy_status->path_cfotail[RF_PATH_A];
+
+ dm_info->curr_rx_rate = pkt_stat->rate;
+ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
+ dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1;
+ /* convert to KHz (used only for debugfs) */
+ dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1;
+
+ /* (EVM value as s8 / 2) is dbm, should usually be in -33 to 0
+ * range. rx_evm_dbm needs the absolute (positive) value.
+ */
+ val_s8 = (s8)pkt_stat->rx_evm[RF_PATH_A];
+ val_s8 = clamp_t(s8, -val_s8 >> 1, 0, 64);
+ val_s8 &= 0x3F; /* 64->0: second path of 1SS rate is 64 */
+ dm_info->rx_evm_dbm[RF_PATH_A] = val_s8;
+}
+
+static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ if (pkt_stat->rate <= DESC_RATE11M)
+ query_phy_status_cck(rtwdev, phy_status, pkt_stat);
+ else
+ query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);
+}
+
+static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_rx_status *rx_status)
+{
+ struct ieee80211_hdr *hdr;
+ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
+ 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->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B;
+
+ if (pkt_stat->is_c2h)
+ return;
+
+ hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
+ pkt_stat->drv_info_sz);
+
+ pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
+
+ if (pkt_stat->phy_status) {
+ phy_status = rx_desc + desc_sz + pkt_stat->shift;
+ query_phy_status(rtwdev, phy_status, pkt_stat);
+ }
+
+ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
+
+ /* Rtl8723cs driver checks for size < 14 or size > 8192 and
+ * simply drops the packet. Maybe this should go into
+ * rtw_rx_fill_rx_status()?
+ */
+ if (pkt_stat->pkt_len == 0) {
+ rx_status->flag |= RX_FLAG_NO_PSDU;
+ rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
+ }
+}
+
+#define ADDA_ON_VAL_8703B 0x03c00014
+
+static
+void rtw8703b_iqk_config_mac(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[0], 0x3F);
+ for (int i = 1; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
+ rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i],
+ backup->mac8[i] & (~BIT(3)));
+}
+
+#define IQK_LTE_WRITE_VAL_8703B 0x00007700
+#define IQK_DELAY_TIME_8703B 4
+
+static void rtw8703b_iqk_one_shot(struct rtw_dev *rtwdev, bool tx)
+{
+ u32 regval;
+ ktime_t t;
+ s64 dur;
+ int ret;
+
+ /* enter IQK mode */
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
+ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B);
+
+ /* One shot, LOK & IQK */
+ rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000);
+ rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000);
+
+ t = ktime_get();
+ msleep(IQK_DELAY_TIME_8703B);
+ ret = read_poll_timeout(rtw_read32, regval, regval != 0, 1000,
+ 100000, false, rtwdev,
+ REG_IQK_RDY);
+ dur = ktime_us_delta(ktime_get(), t);
+
+ if (ret)
+ rtw_warn(rtwdev, "[IQK] %s timed out after %lldus!\n",
+ tx ? "TX" : "RX", dur);
+ else
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] %s done after %lldus\n",
+ tx ? "TX" : "RX", dur);
+}
+
+static void rtw8703b_iqk_txrx_path_post(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup);
+ rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg);
+
+ /* leave IQK mode */
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x0);
+}
+
+static u8 rtw8703b_iqk_check_tx_failed(struct rtw_dev *rtwdev)
+{
+ s32 tx_x, tx_y;
+ u32 tx_fail;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n",
+ rtw_read32(rtwdev, REG_IQK_RES_RY));
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n",
+ rtw_read32(rtwdev, REG_IQK_RES_TX),
+ rtw_read32(rtwdev, REG_IQK_RES_TY));
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] 0xe90(before IQK) = 0x%x, 0xe98(after IQK) = 0x%x\n",
+ rtw_read32(rtwdev, REG_IQK_RDY),
+ rtw_read32(rtwdev, 0xe98));
+
+ tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL);
+ tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);
+ tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);
+
+ if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR)
+ return IQK_TX_OK;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A TX IQK failed\n");
+
+ return 0;
+}
+
+static u8 rtw8703b_iqk_check_rx_failed(struct rtw_dev *rtwdev)
+{
+ s32 rx_x, rx_y;
+ u32 rx_fail;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n",
+ rtw_read32(rtwdev, REG_IQK_RES_RX),
+ rtw_read32(rtwdev, REG_IQK_RES_RY));
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] 0xea0(before IQK) = 0x%x, 0xea8(after IQK) = 0x%x\n",
+ rtw_read32(rtwdev, 0xea0),
+ rtw_read32(rtwdev, 0xea8));
+
+ rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL);
+ rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX);
+ rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY);
+ rx_y = abs(iqkxy_to_s32(rx_y));
+
+ if (!rx_fail && rx_x != IQK_RX_X_ERR && rx_y != IQK_RX_Y_ERR &&
+ rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER &&
+ rx_y < IQK_RX_Y_LMT)
+ return IQK_RX_OK;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A RX IQK failed\n");
+
+ return 0;
+}
+
+static u8 rtw8703b_iqk_tx_path(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ u8 status;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK!\n");
+
+ /* IQK setting */
+ rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);
+ rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
+ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c);
+ rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);
+ rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);
+ rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);
+ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f);
+ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);
+ rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);
+ rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);
+
+ /* LO calibration setting */
+ rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911);
+
+ /* leave IQK mode */
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000);
+
+ /* PA, PAD setting */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x7);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x7f, RFREG_MASK, 0xd400);
+
+ rtw8703b_iqk_one_shot(rtwdev, true);
+ status = rtw8703b_iqk_check_tx_failed(rtwdev);
+
+ rtw8703b_iqk_txrx_path_post(rtwdev, backup);
+
+ return status;
+}
+
+static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ u8 status;
+ u32 tx_x, tx_y;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 1!\n");
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK1 = 0x%x\n",
+ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
+ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x99000000);
+
+ /* disable IQC mode */
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
+
+ /* IQK setting */
+ rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);
+ rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
+
+ /* path IQK setting */
+ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c);
+ rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);
+ rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);
+ rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);
+ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8216000f);
+ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);
+ rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000);
+ rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);
+
+ /* LOK setting */
+ rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911);
+
+ /* RX IQK mode */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0x57db7);
+
+ rtw8703b_iqk_one_shot(rtwdev, true);
+ /* leave IQK mode */
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000);
+ status = rtw8703b_iqk_check_tx_failed(rtwdev);
+
+ if (!status)
+ goto restore;
+
+ /* second round */
+ tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);
+ tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);
+
+ rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y));
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n",
+ rtw_read32(rtwdev, REG_TXIQK_11N),
+ BIT_SET_TXIQK_11N(tx_x, tx_y));
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 2!\n");
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK 2 = 0x%x\n",
+ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
+
+ /* IQK setting */
+ rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
+ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c);
+ rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c);
+ rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);
+ rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);
+ rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82110000);
+ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160c1f);
+ rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);
+ rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);
+
+ /* LO calibration setting */
+ rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1);
+
+ /* leave IQK mode */
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000);
+ /* modify RX IQK mode table */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);
+ /* RF_RCK_OS, RF_TXPA_G1, RF_TXPA_G2 */
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0xf7d77);
+
+ /* PA, PAD setting */
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x5);
+
+ rtw8703b_iqk_one_shot(rtwdev, false);
+ status |= rtw8703b_iqk_check_rx_failed(rtwdev);
+
+restore:
+ rtw8703b_iqk_txrx_path_post(rtwdev, backup);
+
+ return status;
+}
+
+static
+void rtw8703b_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,
+ const struct rtw8723x_iqk_backup_regs *backup)
+{
+ u32 i;
+ u8 a_ok;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t);
+
+ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8703B);
+ rtw8703b_iqk_config_mac(rtwdev, backup);
+ rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf);
+ rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05600);
+ rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4);
+ rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204000);
+
+ for (i = 0; i < PATH_IQK_RETRY; i++) {
+ a_ok = rtw8703b_iqk_tx_path(rtwdev, backup);
+ if (a_ok == IQK_TX_OK) {
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] path A TX IQK success!\n");
+ result[t][IQK_S1_TX_X] =
+ rtw_read32_mask(rtwdev, REG_IQK_RES_TX,
+ BIT_MASK_RES_TX);
+ result[t][IQK_S1_TX_Y] =
+ rtw_read32_mask(rtwdev, REG_IQK_RES_TY,
+ BIT_MASK_RES_TY);
+ break;
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK fail!\n");
+ result[t][IQK_S1_TX_X] = 0x100;
+ result[t][IQK_S1_TX_Y] = 0x0;
+ }
+
+ for (i = 0; i < PATH_IQK_RETRY; i++) {
+ a_ok = rtw8703b_iqk_rx_path(rtwdev, backup);
+ if (a_ok == (IQK_TX_OK | IQK_RX_OK)) {
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] path A RX IQK success!\n");
+ result[t][IQK_S1_RX_X] =
+ rtw_read32_mask(rtwdev, REG_IQK_RES_RX,
+ BIT_MASK_RES_RX);
+ result[t][IQK_S1_RX_Y] =
+ rtw_read32_mask(rtwdev, REG_IQK_RES_RY,
+ BIT_MASK_RES_RY);
+ break;
+ }
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK fail!\n");
+ result[t][IQK_S1_RX_X] = 0x100;
+ result[t][IQK_S1_RX_Y] = 0x0;
+ }
+
+ if (a_ok == 0x0)
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A IQK fail!\n");
+
+ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
+ mdelay(1);
+}
+
+static
+void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[])
+{
+ u32 tmp_rx_iqi = 0x40000100 & GENMASK(31, 16);
+ s32 tx1_a, tx1_a_ext;
+ s32 tx1_c, tx1_c_ext;
+ s32 oldval_1;
+ s32 x, y;
+
+ if (result[IQK_S1_TX_X] == 0)
+ return;
+
+ oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
+ BIT_MASK_TXIQ_ELM_D);
+
+ x = iqkxy_to_s32(result[IQK_S1_TX_X]);
+ tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext);
+ rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
+ BIT_MASK_TXIQ_ELM_A, tx1_a);
+ rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD,
+ BIT_MASK_OFDM0_EXT_A, tx1_a_ext);
+
+ y = iqkxy_to_s32(result[IQK_S1_TX_Y]);
+ tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext);
+ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,
+ BIT_SET_TXIQ_ELM_C1(tx1_c));
+ rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
+ BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c));
+ rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD,
+ BIT_MASK_OFDM0_EXT_C, tx1_c_ext);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n",
+ x, tx1_a, oldval_1);
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c);
+
+ if (result[IQK_S1_RX_X] == 0)
+ return;
+
+ tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]);
+ tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_X]);
+ rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi);
+ rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2,
+ BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y]));
+}
+
+static void rtw8703b_phy_calibration(struct rtw_dev *rtwdev)
+{
+ /* For some reason path A is called S1 and B S0 in shared
+ * rtw88 calibration data.
+ */
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw8723x_iqk_backup_regs backup;
+ u8 final_candidate = IQK_ROUND_INVALID;
+ s32 result[IQK_ROUND_SIZE][IQK_NR];
+ bool good;
+ u8 i, j;
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!\n");
+
+ memset(result, 0, sizeof(result));
+
+ rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup);
+ rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup);
+ rtw8723x_iqk_backup_regs(rtwdev, &backup);
+
+ for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) {
+ rtw8723x_iqk_config_path_ctrl(rtwdev);
+ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B);
+
+ rtw8703b_iqk_one_round(rtwdev, result, i, &backup);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] back to BB mode, load original values!\n");
+ if (i > IQK_ROUND_0)
+ rtw8723x_iqk_restore_regs(rtwdev, &backup);
+ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup);
+ rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup);
+
+ for (j = IQK_ROUND_0; j < i; j++) {
+ good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i);
+
+ if (good) {
+ final_candidate = j;
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] cmp %d:%d final_candidate is %x\n",
+ j, i, final_candidate);
+ goto iqk_done;
+ }
+ }
+ }
+
+ if (final_candidate == IQK_ROUND_INVALID) {
+ s32 reg_tmp = 0;
+
+ for (i = 0; i < IQK_NR; i++)
+ reg_tmp += result[IQK_ROUND_HYBRID][i];
+
+ if (reg_tmp != 0) {
+ final_candidate = IQK_ROUND_HYBRID;
+ } else {
+ WARN(1, "IQK failed\n");
+ goto out;
+ }
+ }
+
+iqk_done:
+ /* only path A is calibrated in rtl8703b */
+ rtw8703b_iqk_fill_a_matrix(rtwdev, result[final_candidate]);
+
+ dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X];
+ dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y];
+ dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X];
+ dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y];
+ dm_info->iqk.done = true;
+
+out:
+ rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg);
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n",
+ final_candidate);
+
+ for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++)
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n",
+ i,
+ result[i][0], result[i][1], result[i][2], result[i][3],
+ result[i][4], result[i][5], result[i][6], result[i][7],
+ final_candidate == i ? "(final candidate)" : "");
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] 0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n",
+ rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE),
+ rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N),
+ rtw_read32(rtwdev, REG_A_RXIQI),
+ rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N));
+ rtw_dbg(rtwdev, RTW_DBG_RFK,
+ "[IQK] 0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n",
+ rtw_read32(rtwdev, REG_TXIQ_AB_S0),
+ rtw_read32(rtwdev, REG_TXIQ_CD_S0),
+ rtw_read32(rtwdev, REG_RXIQ_AB_S0));
+
+ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Finished.\n");
+}
+
+static void rtw8703b_set_iqk_matrix_by_result(struct rtw_dev *rtwdev,
+ u32 ofdm_swing, u8 rf_path)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ s32 ele_A, ele_D, ele_C;
+ s32 ele_A_ext, ele_C_ext, ele_D_ext;
+ s32 iqk_result_x;
+ s32 iqk_result_y;
+ s32 value32;
+
+ switch (rf_path) {
+ default:
+ case RF_PATH_A:
+ iqk_result_x = dm_info->iqk.result.s1_x;
+ iqk_result_y = dm_info->iqk.result.s1_y;
+ break;
+ case RF_PATH_B:
+ iqk_result_x = dm_info->iqk.result.s0_x;
+ iqk_result_y = dm_info->iqk.result.s0_y;
+ break;
+ }
+
+ /* new element D */
+ ele_D = OFDM_SWING_D(ofdm_swing);
+ iqk_mult(iqk_result_x, ele_D, &ele_D_ext);
+ /* new element A */
+ iqk_result_x = iqkxy_to_s32(iqk_result_x);
+ ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext);
+ /* new element C */
+ iqk_result_y = iqkxy_to_s32(iqk_result_y);
+ ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext);
+
+ switch (rf_path) {
+ case RF_PATH_A:
+ default:
+ /* write new elements A, C, D, and element B is always 0 */
+ value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D);
+ rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32);
+ value32 = BIT_SET_TXIQ_ELM_C1(ele_C);
+ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,
+ value32);
+ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);
+ value32 &= ~BIT_MASK_OFDM0_EXTS;
+ value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext);
+ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);
+ break;
+
+ case RF_PATH_B:
+ /* write new elements A, C, D, and element B is always 0 */
+ value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D);
+ rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, value32);
+ value32 = BIT_SET_TXIQ_ELM_C1(ele_C);
+ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS,
+ value32);
+ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);
+ value32 &= ~BIT_MASK_OFDM0_EXTS_B;
+ value32 |= BIT_SET_OFDM0_EXTS_B(ele_A_ext, ele_C_ext, ele_D_ext);
+ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);
+ break;
+ }
+}
+
+static void rtw8703b_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index,
+ u8 rf_path)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ s32 value32;
+ u32 ofdm_swing;
+
+ ofdm_index = clamp_t(s8, ofdm_index, 0, RTW_OFDM_SWING_TABLE_SIZE - 1);
+
+ ofdm_swing = rtw8703b_ofdm_swing_table[ofdm_index];
+
+ if (dm_info->iqk.done) {
+ rtw8703b_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path);
+ return;
+ }
+
+ switch (rf_path) {
+ case RF_PATH_A:
+ default:
+ rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing);
+ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,
+ 0x00);
+
+ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);
+ value32 &= ~BIT_MASK_OFDM0_EXTS;
+ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);
+ break;
+
+ case RF_PATH_B:
+ rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, ofdm_swing);
+ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS,
+ 0x00);
+
+ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);
+ value32 &= ~BIT_MASK_OFDM0_EXTS_B;
+ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);
+ break;
+ }
+}
+
+static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
+ s8 txagc_idx)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ dm_info->txagc_remnant_ofdm = txagc_idx;
+
+ /* Only path A is calibrated for rtl8703b */
+ rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
+}
+
+static void rtw8703b_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
+ s8 txagc_idx)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ dm_info->txagc_remnant_cck = txagc_idx;
+
+ swing_idx = clamp_t(s8, swing_idx, 0, RTW_CCK_SWING_TABLE_SIZE - 1);
+
+ BUILD_BUG_ON(ARRAY_SIZE(rtw8703b_cck_pwr_regs)
+ != ARRAY_SIZE(rtw8703b_cck_swing_table[0]));
+
+ for (int i = 0; i < ARRAY_SIZE(rtw8703b_cck_pwr_regs); i++)
+ rtw_write8(rtwdev, rtw8703b_cck_pwr_regs[i],
+ rtw8703b_cck_swing_table[swing_idx][i]);
+}
+
+static void rtw8703b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_hal *hal = &rtwdev->hal;
+ u8 limit_ofdm;
+ u8 limit_cck = 21;
+ s8 final_ofdm_swing_index;
+ s8 final_cck_swing_index;
+
+ limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev);
+
+ final_ofdm_swing_index = dm_info->default_ofdm_index +
+ dm_info->delta_power_index[path];
+ final_cck_swing_index = dm_info->default_cck_index +
+ dm_info->delta_power_index[path];
+
+ if (final_ofdm_swing_index > limit_ofdm)
+ rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm,
+ final_ofdm_swing_index - limit_ofdm);
+ else if (final_ofdm_swing_index < 0)
+ rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, 0,
+ final_ofdm_swing_index);
+ else
+ rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0);
+
+ if (final_cck_swing_index > limit_cck)
+ rtw8703b_pwrtrack_set_cck_pwr(rtwdev, limit_cck,
+ final_cck_swing_index - limit_cck);
+ else if (final_cck_swing_index < 0)
+ rtw8703b_pwrtrack_set_cck_pwr(rtwdev, 0,
+ final_cck_swing_index);
+ else
+ rtw8703b_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0);
+
+ rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
+}
+
+static void rtw8703b_phy_pwrtrack(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_swing_table swing_table;
+ u8 thermal_value, delta, path;
+ bool do_iqk = false;
+
+ rtw_phy_config_swing_table(rtwdev, &swing_table);
+
+ if (rtwdev->efuse.thermal_meter[0] == 0xff)
+ return;
+
+ thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
+
+ rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
+
+ do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev);
+
+ if (do_iqk)
+ rtw8723x_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);
+
+ delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1);
+
+ for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
+ s8 delta_cur, delta_last;
+
+ delta_last = dm_info->delta_power_index[path];
+ delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table,
+ path, RF_PATH_A, delta);
+ if (delta_last == delta_cur)
+ continue;
+
+ dm_info->delta_power_index[path] = delta_cur;
+ rtw8703b_pwrtrack_set(rtwdev, path);
+ }
+
+ rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta);
+
+iqk:
+ if (do_iqk)
+ rtw8703b_phy_calibration(rtwdev);
+}
+
+static void rtw8703b_pwr_track(struct rtw_dev *rtwdev)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ if (efuse->power_track_type != 0) {
+ rtw_warn(rtwdev, "unsupported power track type");
+ return;
+ }
+
+ 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;
+ }
+
+ rtw8703b_phy_pwrtrack(rtwdev);
+ dm_info->pwr_trk_triggered = false;
+}
+
+static void rtw8703b_coex_set_gnt_fix(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8703b_coex_set_gnt_debug(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw8703b_coex_set_rfe_type(struct rtw_dev *rtwdev)
+{
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_rfe *coex_rfe = &coex->rfe;
+
+ coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;
+ coex_rfe->ant_switch_polarity = 0;
+ coex_rfe->ant_switch_exist = false;
+ coex_rfe->ant_switch_with_bt = false;
+ coex_rfe->ant_switch_diversity = false;
+ coex_rfe->wlg_at_btg = true;
+
+ /* disable LTE coex on wifi side */
+ rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0);
+ rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);
+ rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);
+}
+
+static void rtw8703b_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
+{
+}
+
+static void rtw8703b_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
+{
+}
+
+static const u8 rtw8703b_pwrtrk_2gb_n[] = {
+ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
+ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11
+};
+
+static const u8 rtw8703b_pwrtrk_2gb_p[] = {
+ 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15
+};
+
+static const u8 rtw8703b_pwrtrk_2ga_n[] = {
+ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
+ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11
+};
+
+static const u8 rtw8703b_pwrtrk_2ga_p[] = {
+ 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15
+};
+
+static const u8 rtw8703b_pwrtrk_2g_cck_b_n[] = {
+ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
+ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11
+};
+
+static const u8 rtw8703b_pwrtrk_2g_cck_b_p[] = {
+ 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6,
+ 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13
+};
+
+static const u8 rtw8703b_pwrtrk_2g_cck_a_n[] = {
+ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
+ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11
+};
+
+static const u8 rtw8703b_pwrtrk_2g_cck_a_p[] = {
+ 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6,
+ 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13
+};
+
+static const s8 rtw8703b_pwrtrk_xtal_n[] = {
+ 0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -3, -3, -3, -3, -3,
+ -4, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1
+};
+
+static const s8 rtw8703b_pwrtrk_xtal_p[] = {
+ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 0, -1, -1, -1,
+ -2, -3, -7, -9, -10, -11, -14, -16, -18, -20, -22, -24, -26, -28, -30
+};
+
+static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = {
+ .pwrtrk_2gb_n = rtw8703b_pwrtrk_2gb_n,
+ .pwrtrk_2gb_p = rtw8703b_pwrtrk_2gb_p,
+ .pwrtrk_2ga_n = rtw8703b_pwrtrk_2ga_n,
+ .pwrtrk_2ga_p = rtw8703b_pwrtrk_2ga_p,
+ .pwrtrk_2g_cckb_n = rtw8703b_pwrtrk_2g_cck_b_n,
+ .pwrtrk_2g_cckb_p = rtw8703b_pwrtrk_2g_cck_b_p,
+ .pwrtrk_2g_ccka_n = rtw8703b_pwrtrk_2g_cck_a_n,
+ .pwrtrk_2g_ccka_p = rtw8703b_pwrtrk_2g_cck_a_p,
+ .pwrtrk_xtal_n = rtw8703b_pwrtrk_xtal_n,
+ .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p,
+};
+
+/* Shared-Antenna Coex Table */
+static const struct coex_table_para table_sant_8703b[] = {
+ {0xffffffff, 0xffffffff}, /* 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, 0x6a5a5aaa},
+ {0x66555555, 0x5a5a5aaa},
+ {0x66555555, 0x6aaa5aaa},
+ {0x66555555, 0xaaaa5aaa},
+ {0x66555555, 0xaaaaaaaa}, /* case-15 */
+ {0xffff55ff, 0xfafafafa},
+ {0xffff55ff, 0x6afa5afa},
+ {0xaaffffaa, 0xfafafafa},
+ {0xaa5555aa, 0x5a5a5a5a},
+ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
+ {0xaa5555aa, 0xaaaaaaaa},
+ {0xffffffff, 0x5a5a5a5a},
+ {0xffffffff, 0x5a5a5a5a},
+ {0xffffffff, 0x55555555},
+ {0xffffffff, 0x5a5a5aaa}, /* case-25 */
+ {0x55555555, 0x5a5a5a5a},
+ {0x55555555, 0xaaaaaaaa},
+ {0x55555555, 0x6a5a6a5a},
+ {0x66556655, 0x66556655},
+ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */
+ {0xffffffff, 0x5aaa5aaa},
+ {0x56555555, 0x5a5a5aaa},
+};
+
+/* Shared-Antenna TDMA */
+static const struct coex_tdma_para tdma_sant_8703b[] = {
+ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
+ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
+ { {0x61, 0x3a, 0x03, 0x11, 0x11} },
+ { {0x61, 0x30, 0x03, 0x11, 0x11} },
+ { {0x61, 0x20, 0x03, 0x11, 0x11} },
+ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
+ { {0x61, 0x45, 0x03, 0x11, 0x10} },
+ { {0x61, 0x3a, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x20, 0x03, 0x11, 0x10} },
+ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
+ { {0x61, 0x08, 0x03, 0x11, 0x14} },
+ { {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, 0x10, 0x50} },
+ { {0x51, 0x30, 0x03, 0x10, 0x50} },
+ { {0x51, 0x20, 0x03, 0x10, 0x50} },
+ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
+ { {0x51, 0x4a, 0x03, 0x10, 0x50} },
+ { {0x51, 0x0c, 0x03, 0x10, 0x54} },
+ { {0x55, 0x08, 0x03, 0x10, 0x54} },
+ { {0x65, 0x10, 0x03, 0x11, 0x10} },
+ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
+ { {0x51, 0x08, 0x03, 0x10, 0x50} },
+ { {0x61, 0x08, 0x03, 0x11, 0x11} },
+};
+
+static struct rtw_chip_ops rtw8703b_ops = {
+ .mac_init = rtw8723x_mac_init,
+ .dump_fw_crash = NULL,
+ .shutdown = NULL,
+ .read_efuse = rtw8703b_read_efuse,
+ .phy_set_param = rtw8703b_phy_set_param,
+ .set_channel = rtw8703b_set_channel,
+ .query_rx_desc = rtw8703b_query_rx_desc,
+ .read_rf = rtw_phy_read_rf_sipi,
+ .write_rf = rtw_phy_write_rf_reg_sipi,
+ .set_tx_power_index = rtw8723x_set_tx_power_index,
+ .set_antenna = NULL,
+ .cfg_ldo25 = rtw8723x_cfg_ldo25,
+ .efuse_grant = rtw8723x_efuse_grant,
+ .false_alarm_statistics = rtw8723x_false_alarm_statistics,
+ .phy_calibration = rtw8703b_phy_calibration,
+ .dpk_track = NULL,
+ /* 8723d uses REG_CSRATIO to set dm_info.cck_pd_default, which
+ * is used in its cck_pd_set function. According to comments
+ * in the vendor driver code it doesn't exist in this chip
+ * generation, only 0xa0a ("ODM_CCK_PD_THRESH", which is only
+ * *written* to).
+ */
+ .cck_pd_set = NULL,
+ .pwr_track = rtw8703b_pwr_track,
+ .config_bfee = NULL,
+ .set_gid_table = NULL,
+ .cfg_csi_rate = NULL,
+ .adaptivity_init = NULL,
+ .adaptivity = NULL,
+ .cfo_init = NULL,
+ .cfo_track = NULL,
+ .config_tx_path = NULL,
+ .config_txrx_mode = NULL,
+ .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum,
+
+ /* for coex */
+ .coex_set_init = rtw8723x_coex_cfg_init,
+ .coex_set_ant_switch = NULL,
+ .coex_set_gnt_fix = rtw8703b_coex_set_gnt_fix,
+ .coex_set_gnt_debug = rtw8703b_coex_set_gnt_debug,
+ .coex_set_rfe_type = rtw8703b_coex_set_rfe_type,
+ .coex_set_wl_tx_power = rtw8703b_coex_set_wl_tx_power,
+ .coex_set_wl_rx_gain = rtw8703b_coex_set_wl_rx_gain,
+};
+
+const struct rtw_chip_info rtw8703b_hw_spec = {
+ .ops = &rtw8703b_ops,
+ .id = RTW_CHIP_TYPE_8703B,
+
+ .fw_name = "rtw88/rtw8703b_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 = 256,
+ .log_efuse_size = 512,
+ .ptct_efuse_size = 15,
+ .txff_size = 32768,
+ .rxff_size = 16384,
+ .rsvd_drv_pg_num = 8,
+ .band = RTW_BAND_2G,
+ .page_size = TX_PAGE_SIZE,
+ .csi_buf_pg_num = 0,
+ .dig_min = 0x20,
+ .txgi_factor = 1,
+ .is_pwr_by_rate_dec = true,
+ .rx_ldpc = false,
+ .tx_stbc = false,
+ .max_power_index = 0x3f,
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+
+ .path_div_supported = false,
+ .ht_supported = true,
+ .vht_supported = false,
+ .lps_deep_mode_supported = 0,
+
+ .sys_func_en = 0xFD,
+ .pwr_on_seq = card_enable_flow_8703b,
+ .pwr_off_seq = card_disable_flow_8703b,
+ .rqpn_table = rqpn_table_8703b,
+ .prioq_addrs = &rtw8723x_common.prioq_addrs,
+ .page_table = page_table_8703b,
+ /* used only in pci.c, not needed for SDIO devices */
+ .intf_table = NULL,
+
+ .dig = rtw8723x_common.dig,
+ .dig_cck = rtw8723x_common.dig_cck,
+
+ .rf_sipi_addr = {0x840, 0x844},
+ .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr,
+ .fix_rf_phy_num = 2,
+ .ltecoex_addr = &rtw8723x_common.ltecoex_addr,
+
+ .mac_tbl = &rtw8703b_mac_tbl,
+ .agc_tbl = &rtw8703b_agc_tbl,
+ .bb_tbl = &rtw8703b_bb_tbl,
+ .rf_tbl = {&rtw8703b_rf_a_tbl},
+
+ .rfe_defs = rtw8703b_rfe_defs,
+ .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",
+ .wowlan_stub = NULL,
+ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
+
+ /* Vendor driver has a time-based format, converted from
+ * 20180330
+ */
+ .coex_para_ver = 0x0133ed6a,
+ .bt_desired_ver = 0x1c,
+ .scbd_support = true,
+ .new_scbd10_def = true,
+ .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,
+ .bt_rssi_step = bt_rssi_step_8703b,
+ .wl_rssi_step = wl_rssi_step_8703b,
+ /* sant -> shared antenna, nsant -> non-shared antenna
+ * Not sure if 8703b versions with non-shard antenna even exist.
+ */
+ .table_sant_num = ARRAY_SIZE(table_sant_8703b),
+ .table_sant = table_sant_8703b,
+ .table_nsant_num = 0,
+ .table_nsant = NULL,
+ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8703b),
+ .tdma_sant = tdma_sant_8703b,
+ .tdma_nsant_num = 0,
+ .tdma_nsant = NULL,
+ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8703b),
+ .wl_rf_para_tx = rf_para_tx_8703b,
+ .wl_rf_para_rx = rf_para_rx_8703b,
+ .bt_afh_span_bw20 = 0x20,
+ .bt_afh_span_bw40 = 0x30,
+ .afh_5g_num = ARRAY_SIZE(afh_5g_8703b),
+ .afh_5g = afh_5g_8703b,
+ /* REG_BTG_SEL doesn't seem to have a counterpart in the
+ * vendor driver. Mathematically it's REG_PAD_CTRL1 + 3.
+ *
+ * It is used in the cardemu_to_act power sequence by though
+ * (by address, 0x0067), comment: "0x67[0] = 0 to disable
+ * BT_GPS_SEL pins" That seems to fit.
+ */
+ .btg_reg = NULL,
+ /* These registers are used to read (and print) from if
+ * CONFIG_RTW88_DEBUGFS is enabled.
+ */
+ .coex_info_hw_regs_num = 0,
+ .coex_info_hw_regs = NULL,
+};
+EXPORT_SYMBOL(rtw8703b_hw_spec);
+
+MODULE_FIRMWARE("rtw88/rtw8703b_fw.bin");
+MODULE_FIRMWARE("rtw88/rtw8703b_wow_fw.bin");
+
+MODULE_AUTHOR("Fiona Klute <[email protected]>");
+MODULE_DESCRIPTION("Realtek 802.11n wireless 8703b driver");
+MODULE_LICENSE("Dual BSD/GPL");
--
2.43.0


2024-03-11 10:38:53

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 2/9] wifi: rtw88: Debug output for rtw8723x EFUSE

Some 8703b chips contain invalid EFUSE data, getting detailed
information is critical when analyzing issues caused by that.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8723x.c | 159 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8723x.h | 11 ++
2 files changed, 170 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
index c23650c5a20..0d0b6c2cb9a 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
@@ -63,6 +63,163 @@ static void __rtw8723x_lck(struct rtw_dev *rtwdev)
rtw_write8(rtwdev, REG_TXPAUSE, 0x00);
}

+#define DBG_EFUSE_VAL(rtwdev, map, name) \
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n", \
+ (map)->name)
+#define DBG_EFUSE_2BYTE(rtwdev, map, name) \
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \
+ (map)->name[0], (map)->name[1])
+
+static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev,
+ struct rtw8723x_efuse *map)
+{
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr);
+ DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id);
+ DBG_EFUSE_2BYTE(rtwdev, map, e.device_id);
+ DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id);
+ DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id);
+}
+
+static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev,
+ struct rtw8723x_efuse *map)
+{
+ DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id);
+ DBG_EFUSE_2BYTE(rtwdev, map, u.product_id);
+ DBG_EFUSE_VAL(rtwdev, map, u.usb_option);
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr);
+}
+
+static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev,
+ struct rtw8723x_efuse *map)
+{
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr);
+}
+
+static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev,
+ struct rtw_txpwr_idx *table,
+ int tx_path_count)
+{
+ if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
+ return;
+
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "Power index table (2.4G):\n");
+ /* CCK base */
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n");
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4 G5\n");
+ for (int i = 0; i < tx_path_count; i++)
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "[%c]: %3u %3u %3u %3u %3u %3u\n",
+ 'A' + i,
+ table[i].pwr_idx_2g.cck_base[0],
+ table[i].pwr_idx_2g.cck_base[1],
+ table[i].pwr_idx_2g.cck_base[2],
+ table[i].pwr_idx_2g.cck_base[3],
+ table[i].pwr_idx_2g.cck_base[4],
+ table[i].pwr_idx_2g.cck_base[5]);
+ /* CCK diff */
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n");
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
+ for (int i = 0; i < tx_path_count; i++)
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "[%c]: %2d %2d %2d %2d\n",
+ 'A' + i, 0 /* no diff for 1S */,
+ table[i].pwr_idx_2g.ht_2s_diff.cck,
+ table[i].pwr_idx_2g.ht_3s_diff.cck,
+ table[i].pwr_idx_2g.ht_4s_diff.cck);
+ /* BW40-1S base */
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n");
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4\n");
+ for (int i = 0; i < tx_path_count; i++)
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "[%c]: %3u %3u %3u %3u %3u\n",
+ 'A' + i,
+ table[i].pwr_idx_2g.bw40_base[0],
+ table[i].pwr_idx_2g.bw40_base[1],
+ table[i].pwr_idx_2g.bw40_base[2],
+ table[i].pwr_idx_2g.bw40_base[3],
+ table[i].pwr_idx_2g.bw40_base[4]);
+ /* OFDM diff */
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n");
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
+ for (int i = 0; i < tx_path_count; i++)
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "[%c]: %2d %2d %2d %2d\n",
+ 'A' + i,
+ table[i].pwr_idx_2g.ht_1s_diff.ofdm,
+ table[i].pwr_idx_2g.ht_2s_diff.ofdm,
+ table[i].pwr_idx_2g.ht_3s_diff.ofdm,
+ table[i].pwr_idx_2g.ht_4s_diff.ofdm);
+ /* BW20 diff */
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n");
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
+ for (int i = 0; i < tx_path_count; i++)
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "[%c]: %2d %2d %2d %2d\n",
+ 'A' + i,
+ table[i].pwr_idx_2g.ht_1s_diff.bw20,
+ table[i].pwr_idx_2g.ht_2s_diff.bw20,
+ table[i].pwr_idx_2g.ht_3s_diff.bw20,
+ table[i].pwr_idx_2g.ht_4s_diff.bw20);
+ /* BW40 diff */
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n");
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
+ for (int i = 0; i < tx_path_count; i++)
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE,
+ "[%c]: %2d %2d %2d %2d\n",
+ 'A' + i, 0 /* no diff for 1S */,
+ table[i].pwr_idx_2g.ht_2s_diff.bw40,
+ table[i].pwr_idx_2g.ht_3s_diff.bw40,
+ table[i].pwr_idx_2g.ht_4s_diff.bw40);
+}
+
+static void efuse_debug_dump(struct rtw_dev *rtwdev,
+ struct rtw8723x_efuse *map)
+{
+ if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
+ return;
+
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n");
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
+ (u8 *)map, sizeof(struct rtw8723x_efuse), false);
+ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n");
+ DBG_EFUSE_VAL(rtwdev, map, rtl_id);
+ DBG_EFUSE_VAL(rtwdev, map, afe);
+ rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4);
+ DBG_EFUSE_VAL(rtwdev, map, channel_plan);
+ DBG_EFUSE_VAL(rtwdev, map, xtal_k);
+ DBG_EFUSE_VAL(rtwdev, map, thermal_meter);
+ DBG_EFUSE_VAL(rtwdev, map, iqk_lck);
+ DBG_EFUSE_VAL(rtwdev, map, pa_type);
+ DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g);
+ DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g);
+ DBG_EFUSE_VAL(rtwdev, map, rf_board_option);
+ DBG_EFUSE_VAL(rtwdev, map, rf_feature_option);
+ DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting);
+ DBG_EFUSE_VAL(rtwdev, map, eeprom_version);
+ DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id);
+ DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g);
+ DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate);
+ DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option);
+ DBG_EFUSE_VAL(rtwdev, map, rfe_option);
+ DBG_EFUSE_2BYTE(rtwdev, map, country_code);
+
+ switch (rtw_hci_type(rtwdev)) {
+ case RTW_HCI_TYPE_PCIE:
+ rtw8723xe_efuse_debug(rtwdev, map);
+ break;
+ case RTW_HCI_TYPE_USB:
+ rtw8723xu_efuse_debug(rtwdev, map);
+ break;
+ case RTW_HCI_TYPE_SDIO:
+ rtw8723xs_efuse_debug(rtwdev, map);
+ break;
+ default:
+ /* unsupported now */
+ break;
+ }
+}
+
static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse,
struct rtw8723x_efuse *map)
{
@@ -88,6 +245,7 @@ static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
int i;

map = (struct rtw8723x_efuse *)log_map;
+ efuse_debug_dump(rtwdev, map);

efuse->rfe_option = 0;
efuse->rf_board_option = map->rf_board_option;
@@ -553,6 +711,7 @@ const struct rtw8723x_common rtw8723x_common = {
.pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal,
.coex_cfg_init = __rtw8723x_coex_cfg_init,
.fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum,
+ .debug_txpwr_limit = __rtw8723x_debug_txpwr_limit,
};
EXPORT_SYMBOL(rtw8723x_common);

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
index cace285fc03..d6dfee5a180 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
@@ -154,6 +154,9 @@ struct rtw8723x_common {
void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
u8 *txdesc);
+ void (*debug_txpwr_limit)(struct rtw_dev *rtwdev,
+ struct rtw_txpwr_idx *table,
+ int tx_path_count);
};

extern const struct rtw8723x_common rtw8723x_common;
@@ -346,6 +349,14 @@ static inline s32 iqk_mult(s32 x, s32 y, s32 *ext)
return (t >> 8); /* Q.16 --> Q.8 */
}

+static inline
+void rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev,
+ struct rtw_txpwr_idx *table,
+ int tx_path_count)
+{
+ rtw8723x_common.debug_txpwr_limit(rtwdev, table, tx_path_count);
+}
+
static inline void rtw8723x_lck(struct rtw_dev *rtwdev)
{
rtw8723x_common.lck(rtwdev);
--
2.43.0


2024-03-11 10:38:36

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 3/9] wifi: rtw88: Add definitions for 8703b chip

default_cck_index is used in power track, the rx_cck_agc_report_type
for RX PHY status. GET_RX_DESC_BW is an RX descriptor field not used
by the other chip drivers.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/main.h | 3 +++
drivers/net/wireless/realtek/rtw88/rtw8723x.h | 11 +++++++++++
drivers/net/wireless/realtek/rtw88/rx.h | 2 ++
3 files changed, 16 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index e14d1da4394..49894331f7b 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -187,6 +187,7 @@ enum rtw_chip_type {
RTW_CHIP_TYPE_8822C,
RTW_CHIP_TYPE_8723D,
RTW_CHIP_TYPE_8821C,
+ RTW_CHIP_TYPE_8703B,
};

enum rtw_tx_queue_type {
@@ -1700,11 +1701,13 @@ struct rtw_dm_info {
s8 delta_power_index[RTW_RF_PATH_MAX];
s8 delta_power_index_last[RTW_RF_PATH_MAX];
u8 default_ofdm_index;
+ u8 default_cck_index;
bool pwr_trk_triggered;
bool pwr_trk_init_trigger;
struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX];
s8 txagc_remnant_cck;
s8 txagc_remnant_ofdm;
+ u8 rx_cck_agc_report_type;

/* backup dack results for each path and I/Q */
u32 dack_adck[RTW_RF_PATH_MAX];
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
index d6dfee5a180..e93bfce994b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
@@ -165,6 +165,8 @@ extern const struct rtw8723x_common rtw8723x_common;
#define MAX_TOLERANCE 5
#define IQK_TX_X_ERR 0x142
#define IQK_TX_Y_ERR 0x42
+#define IQK_RX_X_ERR 0x132
+#define IQK_RX_Y_ERR 0x36
#define IQK_RX_X_UPPER 0x11a
#define IQK_RX_X_LOWER 0xe6
#define IQK_RX_Y_LMT 0x1a
@@ -177,6 +179,10 @@ extern const struct rtw8723x_common rtw8723x_common;
#define DIS_3WIRE 0xccf000c0
#define EN_3WIRE 0xccc000c0
#define START_PSD 0x400000
+#define FREQ_CH5 0xfccd
+#define FREQ_CH6 0xfc4d
+#define FREQ_CH7 0xffcd
+#define FREQ_CH8 0xff4d
#define FREQ_CH13 0xfccd
#define FREQ_CH14 0xff9a
#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0)
@@ -239,10 +245,13 @@ extern const struct rtw8723x_common rtw8723x_common;
#define BIT_MASK_OFDM0_EXT_C BIT(29)
#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28))
#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28))
+#define BIT_MASK_OFDM0_EXTS_B (BIT(27) | BIT(25) | BIT(24))
+#define BIT_SET_OFDM0_EXTS_B(a, c, d) (((a) << 27) | ((c) << 25) | ((d) << 24))
#define REG_OFDM0_XAAGC1 0x0c50
#define REG_OFDM0_XBAGC1 0x0c58
#define REG_AGCRSSI 0x0c78
#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80
+#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88
#define BIT_MASK_TXIQ_ELM_A 0x03ff
#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \
((a) & 0x03ff))
@@ -303,6 +312,8 @@ extern const struct rtw8723x_common rtw8723x_common;
#define REG_IQK_AGC_RSP_11N 0x0e4c
#define REG_TX_IQK_TONE_B 0x0e50
#define REG_RX_IQK_TONE_B 0x0e54
+#define REG_TXIQK_PI_B 0x0e58
+#define REG_RXIQK_PI_B 0x0e5c
#define REG_IQK_RES_TX 0x0e94
#define BIT_MASK_RES_TX GENMASK(25, 16)
#define REG_IQK_RES_TY 0x0e9c
diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h
index 3342e376128..d3668c4efc2 100644
--- a/drivers/net/wireless/realtek/rtw88/rx.h
+++ b/drivers/net/wireless/realtek/rtw88/rx.h
@@ -40,6 +40,8 @@ enum rtw_rx_desc_enc {
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29))
#define GET_RX_DESC_TSFL(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0))
+#define GET_RX_DESC_BW(rxdesc) \
+ (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(31, 24)))

void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
struct sk_buff *skb);
--
2.43.0


2024-03-11 10:38:36

by Fiona Klute

[permalink] [raw]
Subject: [PATCH v4 4/9] wifi: rtw88: Add rtw8703b.h

This is the main header for the new rtw88_8703b chip driver.

Acked-by: Ping-Ke Shih <[email protected]>
Tested-by: Pavel Machek <[email protected]>
Signed-off-by: Fiona Klute <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8703b.h | 102 ++++++++++++++++++
1 file changed, 102 insertions(+)
create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.h

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.h b/drivers/net/wireless/realtek/rtw88/rtw8703b.h
new file mode 100644
index 00000000000..3e2da2e6739
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright Fiona Klute <[email protected]> */
+
+#ifndef __RTW8703B_H__
+#define __RTW8703B_H__
+
+#include "rtw8723x.h"
+
+extern const struct rtw_chip_info rtw8703b_hw_spec;
+
+/* phy status parsing */
+#define VGA_BITS GENMASK(4, 0)
+#define LNA_L_BITS GENMASK(7, 5)
+#define LNA_H_BIT BIT(7)
+/* masks for assembling LNA index from high and low bits */
+#define BIT_LNA_H_MASK BIT(3)
+#define BIT_LNA_L_MASK GENMASK(2, 0)
+
+struct phy_rx_agc_info {
+#ifdef __LITTLE_ENDIAN
+ u8 gain: 7;
+ u8 trsw: 1;
+#else
+ u8 trsw: 1;
+ u8 gain: 7;
+#endif
+} __packed;
+
+/* This struct is called phy_status_rpt_8192cd in the vendor driver,
+ * there might be potential to share it with drivers for other chips
+ * of the same generation.
+ */
+struct phy_status_8703b {
+ struct phy_rx_agc_info path_agc[2];
+ u8 ch_corr[2];
+ u8 cck_sig_qual_ofdm_pwdb_all;
+ /* for CCK: bits 0:4: VGA index, bits 5:7: LNA index (low) */
+ u8 cck_agc_rpt_ofdm_cfosho_a;
+ /* for CCK: bit 7 is high bit of LNA index if long report type */
+ u8 cck_rpt_b_ofdm_cfosho_b;
+ u8 reserved_1;
+ u8 noise_power_db_msb;
+ s8 path_cfotail[2];
+ u8 pcts_mask[2];
+ s8 stream_rxevm[2];
+ u8 path_rxsnr[2];
+ u8 noise_power_db_lsb;
+ u8 reserved_2[3];
+ u8 stream_csi[2];
+ u8 stream_target_csi[2];
+ s8 sig_evm;
+ u8 reserved_3;
+
+#ifdef __LITTLE_ENDIAN
+ u8 antsel_rx_keep_2: 1;
+ u8 sgi_en: 1;
+ u8 rxsc: 2;
+ u8 idle_long: 1;
+ u8 r_ant_train_en: 1;
+ u8 ant_sel_b: 1;
+ u8 ant_sel: 1;
+#else /* __BIG_ENDIAN */
+ u8 ant_sel: 1;
+ u8 ant_sel_b: 1;
+ u8 r_ant_train_en: 1;
+ u8 idle_long: 1;
+ u8 rxsc: 2;
+ u8 sgi_en: 1;
+ u8 antsel_rx_keep_2: 1;
+#endif
+} __packed;
+
+/* Baseband registers */
+#define REG_BB_PWR_SAV5_11N 0x0818
+/* BIT(11) should be 1 for 8703B *and* 8723D, which means LNA uses 4
+ * bit for CCK rates in report, not 3. Vendor driver logs a warning if
+ * it's 0, but handles the case.
+ *
+ * Purpose of other parts of this register is unknown, 8723cs driver
+ * code indicates some other chips use certain bits for antenna
+ * diversity.
+ */
+#define REG_BB_AMP 0x0950
+#define BIT_MASK_RX_LNA (BIT(11))
+
+/* 0xaXX: 40MHz channel settings */
+#define REG_CCK_TXSF2 0x0a24 /* CCK TX filter 2 */
+#define REG_CCK_DBG 0x0a28 /* debug port */
+#define REG_OFDM0_A_TX_AFE 0x0c84
+#define REG_TXIQK_MATRIXB_LSB2_11N 0x0c9c
+#define REG_OFDM0_TX_PSD_NOISE 0x0ce4 /* TX pseudo noise weighting */
+#define REG_IQK_RDY 0x0e90 /* is != 0 when IQK is done */
+
+/* RF registers */
+#define RF_RCK1 0x1E
+
+#define AGG_BURST_NUM 3
+#define AGG_BURST_SIZE 0 /* 1K */
+#define BIT_MASK_AGG_BURST_NUM (GENMASK(3, 2))
+#define BIT_MASK_AGG_BURST_SIZE (GENMASK(5, 4))
+
+#endif /* __RTW8703B_H__ */
--
2.43.0