From: Ping-Ke Shih <pkshih@realtek.com>
To: <linux-wireless@vger.kernel.org>
Subject: [PATCH v2 rtw-next 3/7] wifi: rtw89: 8922d: define efuse map and read necessary fields
Date: Tue, 24 Mar 2026 14:20:45 +0800 [thread overview]
Message-ID: <20260324062049.52266-4-pkshih@realtek.com> (raw)
In-Reply-To: <20260324062049.52266-1-pkshih@realtek.com>
Define specific efuse map for RTL8922D, including TSSI, RX gain, MAC
address, RFE type and etc. The additional fields comparing to existing
chips are BT setting (define BT switch GPIO, antenna number and etc) and
gain offset2 (define more fields like existing RX gain offset).
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
v2: no change
---
drivers/net/wireless/realtek/rtw89/core.h | 3 +
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 162 ++++++++++++++++++
drivers/net/wireless/realtek/rtw89/rtw8922d.h | 70 ++++++++
3 files changed, 235 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 94e4faf70e12..d0ae3e15253b 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3562,6 +3562,8 @@ struct rtw89_efuse {
u8 rfe_type;
char country_code[2];
u8 adc_td;
+ u8 bt_setting_2;
+ u8 bt_setting_3;
};
struct rtw89_phy_rate_pattern {
@@ -5926,6 +5928,7 @@ struct rtw89_phy_efuse_gain {
bool offset_valid;
bool comp_valid;
s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */
+ s8 offset2[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */
s8 offset_base[RTW89_PHY_NUM]; /* S(8, 4) */
s8 rssi_base[RTW89_PHY_NUM]; /* S(8, 4) */
s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 194e2901232b..0ae34a4f8d79 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2026 Realtek Corporation
*/
+#include "debug.h"
#include "efuse.h"
#include "mac.h"
#include "reg.h"
@@ -468,6 +469,167 @@ static int rtw8922d_pwr_off_func(struct rtw89_dev *rtwdev)
return 0;
}
+static void rtw8922d_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
+ struct rtw8922d_efuse *map)
+{
+ const struct rtw8922d_tssi_offset_6g * const ofst_6g[] = {
+ &map->path_a_tssi_6g,
+ &map->path_b_tssi_6g,
+ };
+ const struct rtw8922d_tssi_offset * const ofst[] = {
+ &map->path_a_tssi,
+ &map->path_b_tssi,
+ };
+ struct rtw89_tssi_info *tssi = &rtwdev->tssi;
+ u8 i, j;
+
+ tssi->thermal[RF_PATH_A] = map->path_a_therm;
+ tssi->thermal[RF_PATH_B] = map->path_b_therm;
+
+ for (i = 0; i < RF_PATH_NUM_8922D; i++) {
+ memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, TSSI_CCK_CH_GROUP_NUM);
+
+ for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
+ i, j, tssi->tssi_cck[i][j]);
+
+ memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
+ TSSI_MCS_2G_CH_GROUP_NUM);
+ memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
+ ofst[i]->bw40_1s_tssi_5g, TSSI_MCS_5G_CH_GROUP_NUM);
+ memcpy(tssi->tssi_6g_mcs[i], ofst_6g[i]->bw40_1s_tssi_6g,
+ TSSI_MCS_6G_CH_GROUP_NUM);
+
+ for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
+ i, j, tssi->tssi_mcs[i][j]);
+
+ for (j = 0; j < TSSI_MCS_6G_CH_GROUP_NUM; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][EFUSE] path=%d mcs_6g[%d]=0x%x\n",
+ i, j, tssi->tssi_6g_mcs[i][j]);
+ }
+}
+
+static void
+__rtw8922d_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
+ s8 offset[RTW89_GAIN_OFFSET_NR],
+ const s8 *offset_default,
+ const struct rtw8922d_rx_gain *rx_gain,
+ const struct rtw8922d_rx_gain_6g *rx_gain_6g)
+{
+ int i;
+ u8 t;
+
+ offset[RTW89_GAIN_OFFSET_2G_CCK] = rx_gain->_2g_cck;
+ offset[RTW89_GAIN_OFFSET_2G_OFDM] = rx_gain->_2g_ofdm;
+ offset[RTW89_GAIN_OFFSET_5G_LOW] = rx_gain->_5g_low;
+ offset[RTW89_GAIN_OFFSET_5G_MID] = rx_gain->_5g_mid;
+ offset[RTW89_GAIN_OFFSET_5G_HIGH] = rx_gain->_5g_high;
+ offset[RTW89_GAIN_OFFSET_6G_L0] = rx_gain_6g->_6g_l0;
+ offset[RTW89_GAIN_OFFSET_6G_L1] = rx_gain_6g->_6g_l1;
+ offset[RTW89_GAIN_OFFSET_6G_M0] = rx_gain_6g->_6g_m0;
+ offset[RTW89_GAIN_OFFSET_6G_M1] = rx_gain_6g->_6g_m1;
+ offset[RTW89_GAIN_OFFSET_6G_H0] = rx_gain_6g->_6g_h0;
+ offset[RTW89_GAIN_OFFSET_6G_H1] = rx_gain_6g->_6g_h1;
+ offset[RTW89_GAIN_OFFSET_6G_UH0] = rx_gain_6g->_6g_uh0;
+ offset[RTW89_GAIN_OFFSET_6G_UH1] = rx_gain_6g->_6g_uh1;
+
+ for (i = 0; i < RTW89_GAIN_OFFSET_NR; i++) {
+ t = offset[i];
+ if (t == 0xff) {
+ if (offset_default) {
+ offset[i] = offset_default[i];
+ continue;
+ }
+ t = 0;
+ }
+
+ /* transform: sign-bit + U(7,2) to S(8,2) */
+ if (t & 0x80)
+ offset[i] = (t ^ 0x7f) + 1;
+ else
+ offset[i] = t;
+ }
+}
+
+static void rtw8922d_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
+ struct rtw8922d_efuse *map)
+{
+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
+
+ __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset[RF_PATH_A],
+ NULL,
+ &map->rx_gain_a, &map->rx_gain_6g_a);
+ __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset[RF_PATH_B],
+ NULL,
+ &map->rx_gain_b, &map->rx_gain_6g_b);
+
+ __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset2[RF_PATH_A],
+ gain->offset[RF_PATH_A],
+ &map->rx_gain_a_2, &map->rx_gain_6g_a_2);
+ __rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset2[RF_PATH_B],
+ gain->offset[RF_PATH_B],
+ &map->rx_gain_b_2, &map->rx_gain_6g_b_2);
+
+ gain->offset_valid = true;
+}
+
+static int rtw8922d_read_efuse_pci_sdio(struct rtw89_dev *rtwdev, u8 *log_map)
+{
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+
+ if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
+ ether_addr_copy(efuse->addr, log_map + 0x4104);
+ else
+ ether_addr_copy(efuse->addr, log_map + 0x001A);
+
+ return 0;
+}
+
+static int rtw8922d_read_efuse_usb(struct rtw89_dev *rtwdev, u8 *log_map)
+{
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+
+ ether_addr_copy(efuse->addr, log_map + 0x0078);
+
+ return 0;
+}
+
+static int rtw8922d_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map)
+{
+ struct rtw8922d_efuse *map = (struct rtw8922d_efuse *)log_map;
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+
+ efuse->rfe_type = map->rfe_type;
+ efuse->xtal_cap = map->xtal_k;
+ efuse->country_code[0] = map->country_code[0];
+ efuse->country_code[1] = map->country_code[1];
+ efuse->bt_setting_2 = map->bt_setting_2;
+ efuse->bt_setting_3 = map->bt_setting_3;
+ rtw8922d_efuse_parsing_tssi(rtwdev, map);
+ rtw8922d_efuse_parsing_gain_offset(rtwdev, map);
+
+ return 0;
+}
+
+static int rtw8922d_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
+ enum rtw89_efuse_block block)
+{
+ switch (block) {
+ case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO:
+ return rtw8922d_read_efuse_pci_sdio(rtwdev, log_map);
+ case RTW89_EFUSE_BLOCK_HCI_DIG_USB:
+ return rtw8922d_read_efuse_usb(rtwdev, log_map);
+ case RTW89_EFUSE_BLOCK_RF:
+ return rtw8922d_read_efuse_rf(rtwdev, log_map);
+ default:
+ return 0;
+ }
+}
+
MODULE_FIRMWARE(RTW8922D_MODULE_FIRMWARE);
MODULE_FIRMWARE(RTW8922DS_MODULE_FIRMWARE);
MODULE_AUTHOR("Realtek Corporation");
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.h b/drivers/net/wireless/realtek/rtw89/rtw8922d.h
index 7ef3f263274e..a3b98ad6636c 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.h
@@ -7,4 +7,74 @@
#include "core.h"
+#define RF_PATH_NUM_8922D 2
+#define BB_PATH_NUM_8922D 2
+
+struct rtw8922d_tssi_offset {
+ u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM];
+ u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM];
+ u8 rsvd[7];
+ u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM];
+ u8 bw_diff_5g[10];
+} __packed;
+
+struct rtw8922d_tssi_offset_6g {
+ u8 bw40_1s_tssi_6g[TSSI_MCS_6G_CH_GROUP_NUM];
+ u8 rsvd[0xa];
+} __packed;
+
+struct rtw8922d_rx_gain {
+ u8 _2g_ofdm;
+ u8 _2g_cck;
+ u8 _5g_low;
+ u8 _5g_mid;
+ u8 _5g_high;
+} __packed;
+
+struct rtw8922d_rx_gain_6g {
+ u8 _6g_l0;
+ u8 _6g_l1;
+ u8 _6g_m0;
+ u8 _6g_m1;
+ u8 _6g_h0;
+ u8 _6g_h1;
+ u8 _6g_uh0;
+ u8 _6g_uh1;
+} __packed;
+
+struct rtw8922d_efuse {
+ u8 country_code[2];
+ u8 rsvd[0xe];
+ struct rtw8922d_tssi_offset path_a_tssi;
+ struct rtw8922d_tssi_offset path_b_tssi;
+ u8 rsvd1[0x54];
+ u8 channel_plan;
+ u8 xtal_k;
+ u8 rsvd2[0x7];
+ u8 board_info;
+ u8 rsvd3[0x8];
+ u8 rfe_type;
+ u8 rsvd4[2];
+ u8 bt_setting_2;
+ u8 bt_setting_3;
+ u8 rsvd4_2;
+ u8 path_a_therm;
+ u8 path_b_therm;
+ u8 rsvd5[0x2];
+ struct rtw8922d_rx_gain rx_gain_a;
+ struct rtw8922d_rx_gain rx_gain_b;
+ u8 rsvd6[0x18];
+ struct rtw8922d_rx_gain rx_gain_a_2;
+ struct rtw8922d_rx_gain rx_gain_b_2;
+ struct rtw8922d_tssi_offset_6g path_a_tssi_6g;
+ struct rtw8922d_tssi_offset_6g path_b_tssi_6g;
+ struct rtw8922d_tssi_offset_6g path_c_tssi_6g;
+ struct rtw8922d_tssi_offset_6g path_d_tssi_6g;
+ struct rtw8922d_rx_gain_6g rx_gain_6g_a;
+ struct rtw8922d_rx_gain_6g rx_gain_6g_b;
+ u8 rsvd7[0x5a];
+ struct rtw8922d_rx_gain_6g rx_gain_6g_a_2;
+ struct rtw8922d_rx_gain_6g rx_gain_6g_b_2;
+} __packed;
+
#endif
--
2.25.1
next prev parent reply other threads:[~2026-03-24 6:21 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-24 6:20 [PATCH v2 rtw-next 0/7] wifi: rtw89: 8922d: add RTL8922D common routine part 1 Ping-Ke Shih
2026-03-24 6:20 ` [PATCH v2 rtw-next 1/7] wifi: rtw89: 8922d: add definition of quota, registers and efuse block Ping-Ke Shih
2026-03-24 6:20 ` [PATCH v2 rtw-next 2/7] wifi: rtw89: 8922d: add power on/off functions Ping-Ke Shih
2026-03-24 6:20 ` Ping-Ke Shih [this message]
2026-03-24 6:20 ` [PATCH v2 rtw-next 4/7] wifi: rtw89: 8922d: read and configure RF by calibration data from efuse physical map Ping-Ke Shih
2026-03-24 6:20 ` [PATCH v2 rtw-next 5/7] wifi: rtw89: 8922d: add set channel of MAC part Ping-Ke Shih
2026-03-24 6:20 ` [PATCH v2 rtw-next 6/7] wifi: rtw89: 8922d: add set channel of BB part Ping-Ke Shih
2026-03-24 6:20 ` [PATCH v2 rtw-next 7/7] wifi: rtw89: 8922d: add set channel of RF part Ping-Ke Shih
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260324062049.52266-4-pkshih@realtek.com \
--to=pkshih@realtek.com \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox