Skip to contentSkip to conversation

wifi: rtw89: 8922a: add firmware RF calibrations

PATCH In review Ping-Ke Shih 2 participants 13 messages Feb 2, 2024 – Feb 6, 2024 Realtek wireless driver (rtw89)

lore
Share & tools
lore

Ping-Ke Shih

author maintainer
#0 lore raw

cover wifi: rtw89: 8922a: add firmware RF calibrations

For WiFi 7 chips, we move RF calibrations from driver to firmware. Driver must trigger them one by one, so add H2C commands to trigger each of them, and add a C2H event to know the result.

Because H2C commands and C2H event go via PCI ring, we should trigger them after PCI enabled, so add a chip_ops::rfk_init_late for this purpose.

Ping-Ke Shih (11):
wifi: rtw89: rfk: add a completion to wait RF calibration report from
C2H event
wifi: rtw89: rfk: send channel information to firmware for RF
calibrations
wifi: rtw89: rfk: add H2C command to trigger IQK
wifi: rtw89: rfk: add H2C command to trigger RX DCK
wifi: rtw89: rfk: add H2C command to trigger DPK
wifi: rtw89: rfk: add H2C command to trigger DACK
wifi: rtw89: rfk: add H2C command to trigger TXGAPK
wifi: rtw89: rfk: add H2C command to trigger TSSI
wifi: rtw89: 8922a: rfk: implement chip_ops to call RF calibrations
wifi: rtw89: 8922a: add chip_ops::rfk_init_late to do initial RF
calibrations later
wifi: rtw89: 8922a: add chip_ops::rfk_hw_init

 drivers/net/wireless/realtek/rtw89/coex.h     |   1 +
 drivers/net/wireless/realtek/rtw89/core.c     |   2 +
 drivers/net/wireless/realtek/rtw89/core.h     |  51 +-
 drivers/net/wireless/realtek/rtw89/fw.c       | 322 ++++++++
 drivers/net/wireless/realtek/rtw89/fw.h       | 134 +++
 drivers/net/wireless/realtek/rtw89/mac.h      |   2 +
 drivers/net/wireless/realtek/rtw89/phy.c      | 775 ++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/phy.h      |  30 +
 drivers/net/wireless/realtek/rtw89/reg.h      |   8 +
 drivers/net/wireless/realtek/rtw89/rtw8851b.c |   2 +
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |   2 +
 drivers/net/wireless/realtek/rtw89/rtw8852b.c |   2 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c |   2 +
 drivers/net/wireless/realtek/rtw89/rtw8922a.c |  79 ++
 .../net/wireless/realtek/rtw89/rtw8922a_rfk.c | 202 +++++
 .../net/wireless/realtek/rtw89/rtw8922a_rfk.h |   1 +
 16 files changed, 1611 insertions(+), 4 deletions(-)
Signature · 1 line
2.25.1
author maintainer
#1 lore raw

PATCH 1/11 wifi: rtw89: rfk: add a completion to wait RF calibration report from C2H event

The RF calibrations should be executed one by one, so add a completion to ensure one is finish before next. The report from C2H event contains state and optional version, and we only check the state for now. We also care about the time a RF calibration takes, so record start time before asking firmware to do calibration and get the delta time when receiving report.

Consider SER recovery, we can't receive C2H event, use half of argument 'ms' as fixed delay that is 2 times of measured maximum time of calibrations.

---
 drivers/net/wireless/realtek/rtw89/core.c |  1 +
 drivers/net/wireless/realtek/rtw89/core.h | 16 +++++++
 drivers/net/wireless/realtek/rtw89/fw.h   |  6 +++
 drivers/net/wireless/realtek/rtw89/phy.c  | 52 +++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/phy.h  |  3 ++
 5 files changed, 78 insertions(+)
drivers/net/wireless/realtek/rtw89/core.c +1 -0
index 260da86bf04a..c6c3e0c0bf84 100644
@@ -4205,6 +4205,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
 	INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work);
 
 	init_completion(&rtwdev->fw.req.completion);
+	init_completion(&rtwdev->rfk_wait.completion);
 
 	schedule_work(&rtwdev->load_firmware_work);
 
drivers/net/wireless/realtek/rtw89/core.h +16 -0
index 30cc77ac78c5..d88a6b9bc4e9 100644
@@ -4252,6 +4252,21 @@ struct rtw89_phy_stat {
 	struct rtw89_pkt_stat last_pkt_stat;
 };
 
+enum rtw89_rfk_report_state {
+	RTW89_RFK_STATE_START = 0x0,
+	RTW89_RFK_STATE_OK = 0x1,
+	RTW89_RFK_STATE_FAIL = 0x2,
+	RTW89_RFK_STATE_TIMEOUT = 0x3,
+	RTW89_RFK_STATE_H2C_CMD_ERR = 0x4,
+};
+
+struct rtw89_rfk_wait_info {
+	struct completion completion;
+	ktime_t start_time;
+	enum rtw89_rfk_report_state state;
+	u8 version;
+};
+
 #define RTW89_DACK_PATH_NR 2
 #define RTW89_DACK_IDX_NR 2
 #define RTW89_DACK_MSBK_NR 16
@@ -4944,6 +4959,7 @@ struct rtw89_dev {
 	DECLARE_BITMAP(pkt_offload, RTW89_MAX_PKT_OFLD_NUM);
 
 	struct rtw89_phy_stat phystat;
+	struct rtw89_rfk_wait_info rfk_wait;
 	struct rtw89_dack_info dack;
 	struct rtw89_iqk_info iqk;
 	struct rtw89_dpk_info dpk;
drivers/net/wireless/realtek/rtw89/fw.h +6 -0
index ae69e455cd64..9a2c50c35f2a 100644
@@ -4013,6 +4013,12 @@ struct rtw89_c2h_rf_txgapk_rpt_log {
 	u8 rsv1;
 } __packed;
 
+struct rtw89_c2h_rfk_report {
+	struct rtw89_c2h_hdr hdr;
+	u8 state; /* enum rtw89_rfk_report_state */
+	u8 version;
+} __packed;
+
 #define RTW89_FW_RSVD_PLE_SIZE 0x800
 
 #define RTW89_FW_BACKTRACE_INFO_SIZE 8
drivers/net/wireless/realtek/rtw89/phy.c +52 -0

61 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/phy.h +3 -0
index 13903ca1eaa9..df915cb0833f 100644
@@ -885,6 +885,9 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
 bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
 void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 			  u32 len, u8 class, u8 func);
+void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev);
+int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
+			      unsigned int ms);
 void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
 void rtw89_phy_cfo_track_work(struct work_struct *work);
 void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
Signature · 1 line
2.25.1
#2 lore raw

Re: [PATCH 01/11] wifi: rtw89: rfk: add a completion to wait RF calibration report from C2H event

Quoted 7 lines · Ping-Ke Shih

The RF calibrations should be executed one by one, so add a completion to ensure one is finish before next. The report from C2H event contains state and optional version, and we only check the state for now. We also care about the time a RF calibration takes, so record start time before asking firmware to do calibration and get the delta time when receiving report.

Quoted 5 lines

Consider SER recovery, we can't receive C2H event, use half of argument 'ms' as fixed delay that is 2 times of measured maximum time of calibrations.

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

ad1c86e92698 wifi: rtw89: rfk: add a completion to wait RF calibration report from C2H event 80f47f82f319 wifi: rtw89: rfk: send channel information to firmware for RF calibrations 9c66da3b19b5 wifi: rtw89: rfk: add H2C command to trigger IQK
32919a043894 wifi: rtw89: rfk: add H2C command to trigger RX DCK
b835141be5a9 wifi: rtw89: rfk: add H2C command to trigger DPK
1a0cba5dc983 wifi: rtw89: rfk: add H2C command to trigger DACK
af41e89ea323 wifi: rtw89: rfk: add H2C command to trigger TXGAPK
bd6f5f27cb2c wifi: rtw89: rfk: add H2C command to trigger TSSI
ff146ec22d5f wifi: rtw89: 8922a: rfk: implement chip_ops to call RF calibrations 7e2629dc843f wifi: rtw89: 8922a: add chip_ops::rfk_init_late to do initial RF calibrations later 4dbd964f33aa wifi: rtw89: 8922a: add chip_ops::rfk_hw_init

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

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
author maintainer
#3 lore raw

PATCH 2/11 wifi: rtw89: rfk: send channel information to firmware for RF calibrations

In reply to Ping-Ke Shih

We are going to do RF calibrations in firmware, so driver needs to provide channel information for calibrations, which can do the same things as they did in driver.

---
 drivers/net/wireless/realtek/rtw89/core.h | 11 ++--
 drivers/net/wireless/realtek/rtw89/fw.c   | 73 +++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/fw.h   | 42 +++++++++++++
 drivers/net/wireless/realtek/rtw89/reg.h  |  2 +
 4 files changed, 124 insertions(+), 4 deletions(-)
drivers/net/wireless/realtek/rtw89/core.h +7 -4
index d88a6b9bc4e9..e049f7b5168b 100644
@@ -4282,15 +4282,18 @@ struct rtw89_dack_info {
 	bool msbk_timeout[RTW89_DACK_PATH_NR];
 };
 
-#define RTW89_IQK_CHS_NR 2
-#define RTW89_IQK_PATH_NR 4
+#define RTW89_RFK_CHS_NR 3
 
 struct rtw89_rfk_mcc_info {
-	u8 ch[RTW89_IQK_CHS_NR];
-	u8 band[RTW89_IQK_CHS_NR];
+	u8 ch[RTW89_RFK_CHS_NR];
+	u8 band[RTW89_RFK_CHS_NR];
+	u8 bw[RTW89_RFK_CHS_NR];
 	u8 table_idx;
 };
 
+#define RTW89_IQK_CHS_NR 2
+#define RTW89_IQK_PATH_NR 4
+
 struct rtw89_lck_info {
 	u8 thermal[RF_PATH_MAX];
 };
drivers/net/wireless/realtek/rtw89/fw.c +73 -0

79 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/fw.h +42 -0

60 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/reg.h +2 -0
index bd7bdd216e5f..9f209f068679 100644
@@ -8730,7 +8730,9 @@
 #define B_PRT_COM_RXBB_V1 GENMASK(4, 0)
 #define B_PRT_COM_DONE BIT(0)
 #define R_COEF_SEL 0x8104
+#define R_COEF_SEL_C1 0x8204
 #define B_COEF_SEL_IQC BIT(0)
+#define B_COEF_SEL_IQC_V1 GENMASK(1, 0)
 #define B_COEF_SEL_MDPD BIT(8)
 #define R_CFIR_SYS 0x8120
 #define R_IQK_RES 0x8124
Signature · 1 line
2.25.1
author maintainer
#4 lore raw

PATCH 3/11 wifi: rtw89: rfk: add H2C command to trigger IQK

In reply to Ping-Ke Shih

IQ signal calibration is a basic and important calibration to yield good RF performance. Do this calibration on AP channel if we are going to connect. During scanning phase, it transmits with low data rate, so without IQK RF performance is still acceptable.

---
 drivers/net/wireless/realtek/rtw89/fw.c | 35 +++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/fw.h |  7 +++++
 2 files changed, 42 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +35 -0
index 5bd3d08a5d25..d2c166ee5c89 100644
@@ -4593,6 +4593,41 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 	return ret;
 }
 
+int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+	struct rtw89_h2c_rf_iqk *h2c;
+	u32 len = sizeof(*h2c);
+	struct sk_buff *skb;
+	int ret;
+
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for h2c RF IQK\n");
+		return -ENOMEM;
+	}
+	skb_put(skb, len);
+	h2c = (struct rtw89_h2c_rf_iqk *)skb->data;
+
+	h2c->phy_idx = cpu_to_le32(phy_idx);
+	h2c->dbcc = cpu_to_le32(rtwdev->dbcc_en);
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
+			      H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len);
+
+	ret = rtw89_h2c_tx(rtwdev, skb, false);
+	if (ret) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
+
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
 			      bool rack, bool dack)
drivers/net/wireless/realtek/rtw89/fw.h +7 -0
index d9316b66ab76..e9c7f9532b0b 100644
@@ -3935,6 +3935,7 @@ enum rtw89_mcc_h2c_func {
 #define H2C_CL_OUTSRC_RF_FW_RFK		0xb
 
 enum rtw89_rfk_offload_h2c_func {
+	H2C_FUNC_RFK_IQK_OFFLOAD = 0x1,
 	H2C_FUNC_RFK_PRE_NOTIFY = 0x8,
 };
 
@@ -3982,6 +3983,11 @@ struct rtw89_fw_h2c_rfk_pre_info {
 	} __packed mlo;
 } __packed;
 
+struct rtw89_h2c_rf_iqk {
+	__le32 phy_idx;
+	__le32 dbcc;
+} __packed;
+
 enum rtw89_rf_log_type {
 	RTW89_RF_RUN_LOG = 0,
 	RTW89_RF_RPT_LOG = 1,
@@ -4169,6 +4175,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 			     enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
 			      bool rack, bool dack);
Signature · 1 line
2.25.1
author maintainer
#5 lore raw

PATCH 4/11 wifi: rtw89: rfk: add H2C command to trigger RX DCK

In reply to Ping-Ke Shih

RX DCK is receiver DC calibration. This will calibrate DC offset to reflect correct received signal strength indicator, so mechanisms like CCA can have normalized values.

---
 drivers/net/wireless/realtek/rtw89/fw.c | 43 +++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/fw.h | 13 ++++++++
 2 files changed, 56 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +43 -0
index d2c166ee5c89..f1239b00479d 100644
@@ -4628,6 +4628,49 @@ int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 	return ret;
 }
 
+int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+						       RTW89_SUB_ENTITY_0);
+	struct rtw89_h2c_rf_rxdck *h2c;
+	u32 len = sizeof(*h2c);
+	struct sk_buff *skb;
+	int ret;
+
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n");
+		return -ENOMEM;
+	}
+	skb_put(skb, len);
+	h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
+
+	h2c->len = len;
+	h2c->phy = phy_idx;
+	h2c->is_afe = false;
+	h2c->kpath = RF_AB;
+	h2c->cur_band = chan->band_type;
+	h2c->cur_bw = chan->band_width;
+	h2c->cur_ch = chan->channel;
+	h2c->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
+			      H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len);
+
+	ret = rtw89_h2c_tx(rtwdev, skb, false);
+	if (ret) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
+
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
 			      bool rack, bool dack)
drivers/net/wireless/realtek/rtw89/fw.h +13 -0
index e9c7f9532b0b..7e803abe47c6 100644
@@ -3936,6 +3936,7 @@ enum rtw89_mcc_h2c_func {
 
 enum rtw89_rfk_offload_h2c_func {
 	H2C_FUNC_RFK_IQK_OFFLOAD = 0x1,
+	H2C_FUNC_RFK_RXDCK_OFFLOAD = 0x6,
 	H2C_FUNC_RFK_PRE_NOTIFY = 0x8,
 };
 
@@ -3988,6 +3989,17 @@ struct rtw89_h2c_rf_iqk {
 	__le32 dbcc;
 } __packed;
 
+struct rtw89_h2c_rf_rxdck {
+	u8 len;
+	u8 phy;
+	u8 is_afe;
+	u8 kpath;
+	u8 cur_band;
+	u8 cur_bw;
+	u8 cur_ch;
+	u8 rxdck_dbg_en;
+} __packed;
+
 enum rtw89_rf_log_type {
 	RTW89_RF_RUN_LOG = 0,
 	RTW89_RF_RPT_LOG = 1,
@@ -4176,6 +4188,7 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 			     enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
 			      bool rack, bool dack);
Signature · 1 line
2.25.1
author maintainer
#6 lore raw

PATCH 5/11 wifi: rtw89: rfk: add H2C command to trigger DPK

In reply to Ping-Ke Shih

DPK is short for digital pre-distortion calibration. It can adjusts digital waveform according to PA linear characteristics dynamically to enhance TX EVM.

---
 drivers/net/wireless/realtek/rtw89/fw.c | 43 +++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/fw.h | 13 ++++++++
 2 files changed, 56 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +43 -0
index f1239b00479d..1218bab049c3 100644
@@ -4628,6 +4628,49 @@ int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 	return ret;
 }
 
+int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+						       RTW89_SUB_ENTITY_0);
+	struct rtw89_h2c_rf_dpk *h2c;
+	u32 len = sizeof(*h2c);
+	struct sk_buff *skb;
+	int ret;
+
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for h2c RF DPK\n");
+		return -ENOMEM;
+	}
+	skb_put(skb, len);
+	h2c = (struct rtw89_h2c_rf_dpk *)skb->data;
+
+	h2c->len = len;
+	h2c->phy = phy_idx;
+	h2c->dpk_enable = true;
+	h2c->kpath = RF_AB;
+	h2c->cur_band = chan->band_type;
+	h2c->cur_bw = chan->band_width;
+	h2c->cur_ch = chan->channel;
+	h2c->dpk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
+			      H2C_FUNC_RFK_DPK_OFFLOAD, 0, 0, len);
+
+	ret = rtw89_h2c_tx(rtwdev, skb, false);
+	if (ret) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
+
 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 {
 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
drivers/net/wireless/realtek/rtw89/fw.h +13 -0
index 7e803abe47c6..f48d21a772aa 100644
@@ -3936,6 +3936,7 @@ enum rtw89_mcc_h2c_func {
 
 enum rtw89_rfk_offload_h2c_func {
 	H2C_FUNC_RFK_IQK_OFFLOAD = 0x1,
+	H2C_FUNC_RFK_DPK_OFFLOAD = 0x3,
 	H2C_FUNC_RFK_RXDCK_OFFLOAD = 0x6,
 	H2C_FUNC_RFK_PRE_NOTIFY = 0x8,
 };
@@ -3989,6 +3990,17 @@ struct rtw89_h2c_rf_iqk {
 	__le32 dbcc;
 } __packed;
 
+struct rtw89_h2c_rf_dpk {
+	u8 len;
+	u8 phy;
+	u8 dpk_enable;
+	u8 kpath;
+	u8 cur_band;
+	u8 cur_bw;
+	u8 cur_ch;
+	u8 dpk_dbg_en;
+} __packed;
+
 struct rtw89_h2c_rf_rxdck {
 	u8 len;
 	u8 phy;
@@ -4188,6 +4200,7 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 			     enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
Signature · 1 line
2.25.1
author maintainer
#7 lore raw

PATCH 6/11 wifi: rtw89: rfk: add H2C command to trigger DACK

In reply to Ping-Ke Shih

DACK (digital-to-analog converters calibration) is used to calibrate DAC to output signals with expected quality.

---
 drivers/net/wireless/realtek/rtw89/fw.c | 36 +++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/fw.h |  8 ++++++
 2 files changed, 44 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +36 -0
index 1218bab049c3..5b6693ffa290 100644
@@ -4671,6 +4671,42 @@ int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 	return ret;
 }
 
+int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+	struct rtw89_h2c_rf_dack *h2c;
+	u32 len = sizeof(*h2c);
+	struct sk_buff *skb;
+	int ret;
+
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for h2c RF DACK\n");
+		return -ENOMEM;
+	}
+	skb_put(skb, len);
+	h2c = (struct rtw89_h2c_rf_dack *)skb->data;
+
+	h2c->len = cpu_to_le32(len);
+	h2c->phy = cpu_to_le32(phy_idx);
+	h2c->type = cpu_to_le32(0);
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
+			      H2C_FUNC_RFK_DACK_OFFLOAD, 0, 0, len);
+
+	ret = rtw89_h2c_tx(rtwdev, skb, false);
+	if (ret) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
+
 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 {
 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
drivers/net/wireless/realtek/rtw89/fw.h +8 -0
index f48d21a772aa..0fdc62fdd25a 100644
@@ -3937,6 +3937,7 @@ enum rtw89_mcc_h2c_func {
 enum rtw89_rfk_offload_h2c_func {
 	H2C_FUNC_RFK_IQK_OFFLOAD = 0x1,
 	H2C_FUNC_RFK_DPK_OFFLOAD = 0x3,
+	H2C_FUNC_RFK_DACK_OFFLOAD = 0x5,
 	H2C_FUNC_RFK_RXDCK_OFFLOAD = 0x6,
 	H2C_FUNC_RFK_PRE_NOTIFY = 0x8,
 };
@@ -4001,6 +4002,12 @@ struct rtw89_h2c_rf_dpk {
 	u8 dpk_dbg_en;
 } __packed;
 
+struct rtw89_h2c_rf_dack {
+	__le32 len;
+	__le32 phy;
+	__le32 type;
+} __packed;
+
 struct rtw89_h2c_rf_rxdck {
 	u8 len;
 	u8 phy;
@@ -4201,6 +4208,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 			     enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
Signature · 1 line
2.25.1
author maintainer
#8 lore raw

PATCH 7/11 wifi: rtw89: rfk: add H2C command to trigger TXGAPK

In reply to Ping-Ke Shih

TXGAPK stands for TX power gap calibration. Use this calibration to compensate TX power gap to output expected power.

---
 drivers/net/wireless/realtek/rtw89/fw.c | 44 +++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/fw.h | 13 ++++++++
 2 files changed, 57 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +44 -0
index 5b6693ffa290..3f5e72209001 100644
@@ -4671,6 +4671,50 @@ int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 	return ret;
 }
 
+int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+						       RTW89_SUB_ENTITY_0);
+	struct rtw89_hal *hal = &rtwdev->hal;
+	struct rtw89_h2c_rf_txgapk *h2c;
+	u32 len = sizeof(*h2c);
+	struct sk_buff *skb;
+	int ret;
+
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXGAPK\n");
+		return -ENOMEM;
+	}
+	skb_put(skb, len);
+	h2c = (struct rtw89_h2c_rf_txgapk *)skb->data;
+
+	h2c->len = len;
+	h2c->ktype = 2;
+	h2c->phy = phy_idx;
+	h2c->kpath = RF_AB;
+	h2c->band = chan->band_type;
+	h2c->bw = chan->band_width;
+	h2c->ch = chan->channel;
+	h2c->cv = hal->cv;
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
+			      H2C_FUNC_RFK_TXGAPK_OFFLOAD, 0, 0, len);
+
+	ret = rtw89_h2c_tx(rtwdev, skb, false);
+	if (ret) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
+
 int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 {
 	struct rtw89_h2c_rf_dack *h2c;
drivers/net/wireless/realtek/rtw89/fw.h +13 -0
index 0fdc62fdd25a..666c3e7ec0d0 100644
@@ -3937,6 +3937,7 @@ enum rtw89_mcc_h2c_func {
 enum rtw89_rfk_offload_h2c_func {
 	H2C_FUNC_RFK_IQK_OFFLOAD = 0x1,
 	H2C_FUNC_RFK_DPK_OFFLOAD = 0x3,
+	H2C_FUNC_RFK_TXGAPK_OFFLOAD = 0x4,
 	H2C_FUNC_RFK_DACK_OFFLOAD = 0x5,
 	H2C_FUNC_RFK_RXDCK_OFFLOAD = 0x6,
 	H2C_FUNC_RFK_PRE_NOTIFY = 0x8,
@@ -4002,6 +4003,17 @@ struct rtw89_h2c_rf_dpk {
 	u8 dpk_dbg_en;
 } __packed;
 
+struct rtw89_h2c_rf_txgapk {
+	u8 len;
+	u8 ktype;
+	u8 phy;
+	u8 kpath;
+	u8 band;
+	u8 bw;
+	u8 ch;
+	u8 cv;
+} __packed;
+
 struct rtw89_h2c_rf_dack {
 	__le32 len;
 	__le32 phy;
@@ -4208,6 +4220,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 			     enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
Signature · 1 line
2.25.1
author maintainer
#9 lore raw

PATCH 8/11 wifi: rtw89: rfk: add H2C command to trigger TSSI

In reply to Ping-Ke Shih

TSSI is short for transmitter signal strength indication, which is a close-loop hardware circuit to feedback actual transmitting power as a reference to adjust power for next transmission.

When connecting and switching bands or channels, do TSSI calibration and reset hardware status to output expected power.

---
 drivers/net/wireless/realtek/rtw89/core.h |   6 +
 drivers/net/wireless/realtek/rtw89/fw.c   |  48 ++
 drivers/net/wireless/realtek/rtw89/fw.h   |  32 ++
 drivers/net/wireless/realtek/rtw89/phy.c  | 607 ++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/phy.h  |   8 +
 5 files changed, 701 insertions(+)
drivers/net/wireless/realtek/rtw89/core.h +6 -0
index e049f7b5168b..ccc9f96fc18b 100644
@@ -17,6 +17,7 @@ struct rtw89_pci_info;
 struct rtw89_mac_gen_def;
 struct rtw89_phy_gen_def;
 struct rtw89_efuse_block_cfg;
+struct rtw89_h2c_rf_tssi;
 struct rtw89_fw_txpwr_track_cfg;
 struct rtw89_phy_rfk_log_fmt;
 
@@ -4471,6 +4472,11 @@ struct rtw89_cfo_tracking_info {
 	u8 lock_cnt;
 };
 
+enum rtw89_tssi_mode {
+	RTW89_TSSI_NORMAL = 0,
+	RTW89_TSSI_SCAN = 1,
+};
+
 enum rtw89_tssi_alimk_band {
 	TSSI_ALIMK_2G = 0,
 	TSSI_ALIMK_5GL,
drivers/net/wireless/realtek/rtw89/fw.c +48 -0

54 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/fw.h +32 -0
index 666c3e7ec0d0..02a7c7b2c8be 100644
@@ -3935,6 +3935,7 @@ enum rtw89_mcc_h2c_func {
 #define H2C_CL_OUTSRC_RF_FW_RFK		0xb
 
 enum rtw89_rfk_offload_h2c_func {
+	H2C_FUNC_RFK_TSSI_OFFLOAD = 0x0,
 	H2C_FUNC_RFK_IQK_OFFLOAD = 0x1,
 	H2C_FUNC_RFK_DPK_OFFLOAD = 0x3,
 	H2C_FUNC_RFK_TXGAPK_OFFLOAD = 0x4,
@@ -3987,6 +3988,35 @@ struct rtw89_fw_h2c_rfk_pre_info {
 	} __packed mlo;
 } __packed;
 
+struct rtw89_h2c_rf_tssi {
+	__le16 len;
+	u8 phy;
+	u8 ch;
+	u8 bw;
+	u8 band;
+	u8 hwtx_en;
+	u8 cv;
+	s8 curr_tssi_cck_de[2];
+	s8 curr_tssi_cck_de_20m[2];
+	s8 curr_tssi_cck_de_40m[2];
+	s8 curr_tssi_efuse_cck_de[2];
+	s8 curr_tssi_ofdm_de[2];
+	s8 curr_tssi_ofdm_de_20m[2];
+	s8 curr_tssi_ofdm_de_40m[2];
+	s8 curr_tssi_ofdm_de_80m[2];
+	s8 curr_tssi_ofdm_de_160m[2];
+	s8 curr_tssi_ofdm_de_320m[2];
+	s8 curr_tssi_efuse_ofdm_de[2];
+	s8 curr_tssi_ofdm_de_diff_20m[2];
+	s8 curr_tssi_ofdm_de_diff_80m[2];
+	s8 curr_tssi_ofdm_de_diff_160m[2];
+	s8 curr_tssi_ofdm_de_diff_320m[2];
+	s8 curr_tssi_trim_de[2];
+	u8 pg_thermal[2];
+	u8 ftable[2][128];
+	u8 tssi_mode;
+} __packed;
+
 struct rtw89_h2c_rf_iqk {
 	__le32 phy_idx;
 	__le32 dbcc;
@@ -4218,6 +4248,8 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
 			     enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+			 enum rtw89_tssi_mode tssi_mode);
 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
drivers/net/wireless/realtek/rtw89/phy.c +607 -0

613 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/phy.h +8 -0
index df915cb0833f..459e919ddd24 100644
@@ -888,6 +888,14 @@ void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev);
 int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
 			      unsigned int ms);
+void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
+					       enum rtw89_phy_idx phy,
+					       const struct rtw89_chan *chan,
+					       struct rtw89_h2c_rf_tssi *h2c);
+void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev,
+					      enum rtw89_phy_idx phy,
+					      const struct rtw89_chan *chan,
+					      struct rtw89_h2c_rf_tssi *h2c);
 void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
 void rtw89_phy_cfo_track_work(struct work_struct *work);
 void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
Signature · 1 line
2.25.1
author maintainer
#10 lore raw

PATCH 9/11 wifi: rtw89: 8922a: rfk: implement chip_ops to call RF calibrations

In reply to Ping-Ke Shih

Calling RF calibrations when interface up, connection, switching bands and going to scan.

For 8922AE, RF calibrations are moved to firmware, so use H2C commands to trigger RF calibrations and wait for a C2H event to indicate completion. Then, do next RF calibration.

---
 drivers/net/wireless/realtek/rtw89/coex.h     |   1 +
 drivers/net/wireless/realtek/rtw89/phy.c      | 115 ++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/phy.h      |  25 +++-
 drivers/net/wireless/realtek/rtw89/rtw8922a.c |  69 +++++++++++
 4 files changed, 207 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtw89/coex.h +1 -0
index 46e25c6f88a6..08121fd899e6 100644
@@ -23,6 +23,7 @@ enum btc_wl_rfk_type {
 	BTC_WRFKT_DACK = 4,
 	BTC_WRFKT_RXDCK = 5,
 	BTC_WRFKT_TSSI = 6,
+	BTC_WRFKT_CHLK = 7,
 };
 
 #define NM_EXEC false
drivers/net/wireless/realtek/rtw89/phy.c +115 -0

133 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/phy.h +22 -3
index 459e919ddd24..d80ddc723e86 100644
@@ -885,9 +885,28 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
 bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
 void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 			  u32 len, u8 class, u8 func);
-void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev);
-int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
-			      unsigned int ms);
+int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
+				    enum rtw89_phy_idx phy_idx,
+				    unsigned int ms);
+int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
+				enum rtw89_phy_idx phy_idx,
+				enum rtw89_tssi_mode tssi_mode,
+				unsigned int ms);
+int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
+			       enum rtw89_phy_idx phy_idx,
+			       unsigned int ms);
+int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
+			       enum rtw89_phy_idx phy_idx,
+			       unsigned int ms);
+int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
+				  enum rtw89_phy_idx phy_idx,
+				  unsigned int ms);
+int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
+				enum rtw89_phy_idx phy_idx,
+				unsigned int ms);
+int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
+				 enum rtw89_phy_idx phy_idx,
+				 unsigned int ms);
 void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
 					       enum rtw89_phy_idx phy,
 					       const struct rtw89_chan *chan,
drivers/net/wireless/realtek/rtw89/rtw8922a.c +69 -0

87 lines not on this page · raw message

Signature · 1 line
2.25.1
author maintainer
#11 lore raw

PATCH 10/11 wifi: rtw89: 8922a: add chip_ops::rfk_init_late to do initial RF calibrations later

In reply to Ping-Ke Shih

The RF calibrations are moved into firmware, so we trigger calibrations by H2C commands and wait for C2H completion events. However, these events can be received only after HCI (i.e. PCI for now) starts, so we should do initial RF calibrations after that.

---
 drivers/net/wireless/realtek/rtw89/core.c     | 1 +
 drivers/net/wireless/realtek/rtw89/core.h     | 9 +++++++++
 drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 +
 drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 +
 drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 +
 drivers/net/wireless/realtek/rtw89/rtw8922a.c | 9 +++++++++
 7 files changed, 23 insertions(+)
drivers/net/wireless/realtek/rtw89/core.c +1 -0
index c6c3e0c0bf84..61a216464b6d 100644
@@ -4101,6 +4101,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
 
 	set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
 
+	rtw89_chip_rfk_init_late(rtwdev);
 	rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
 	rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.log.enable);
 	rtw89_fw_h2c_init_ba_cam(rtwdev);
drivers/net/wireless/realtek/rtw89/core.h +9 -0
index ccc9f96fc18b..270403f6c3d5 100644
@@ -3157,6 +3157,7 @@ struct rtw89_chip_ops {
 	void (*fem_setup)(struct rtw89_dev *rtwdev);
 	void (*rfe_gpio)(struct rtw89_dev *rtwdev);
 	void (*rfk_init)(struct rtw89_dev *rtwdev);
+	void (*rfk_init_late)(struct rtw89_dev *rtwdev);
 	void (*rfk_channel)(struct rtw89_dev *rtwdev);
 	void (*rfk_band_changed)(struct rtw89_dev *rtwdev,
 				 enum rtw89_phy_idx phy_idx);
@@ -5642,6 +5643,14 @@ static inline void rtw89_chip_rfk_init(struct rtw89_dev *rtwdev)
 		chip->ops->rfk_init(rtwdev);
 }
 
+static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+
+	if (chip->ops->rfk_init_late)
+		chip->ops->rfk_init_late(rtwdev);
+}
+
 static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev)
 {
 	const struct rtw89_chip_info *chip = rtwdev->chip;
drivers/net/wireless/realtek/rtw89/rtw8851b.c +1 -0
index 09b23c56aa8e..09e38713bca7 100644
@@ -2311,6 +2311,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
 	.fem_setup		= NULL,
 	.rfe_gpio		= rtw8851b_rfe_gpio,
 	.rfk_init		= rtw8851b_rfk_init,
+	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8851b_rfk_channel,
 	.rfk_band_changed	= rtw8851b_rfk_band_changed,
 	.rfk_scan		= rtw8851b_rfk_scan,
drivers/net/wireless/realtek/rtw89/rtw8852a.c +1 -0
index c28f05bbdccf..01c249dddfb8 100644
@@ -2055,6 +2055,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
 	.fem_setup		= rtw8852a_fem_setup,
 	.rfe_gpio		= NULL,
 	.rfk_init		= rtw8852a_rfk_init,
+	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8852a_rfk_channel,
 	.rfk_band_changed	= rtw8852a_rfk_band_changed,
 	.rfk_scan		= rtw8852a_rfk_scan,
drivers/net/wireless/realtek/rtw89/rtw8852b.c +1 -0
index 18ed372ed5cd..fb6ad335a37a 100644
@@ -2480,6 +2480,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
 	.fem_setup		= NULL,
 	.rfe_gpio		= NULL,
 	.rfk_init		= rtw8852b_rfk_init,
+	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8852b_rfk_channel,
 	.rfk_band_changed	= rtw8852b_rfk_band_changed,
 	.rfk_scan		= rtw8852b_rfk_scan,
drivers/net/wireless/realtek/rtw89/rtw8852c.c +1 -0
index 431acfaba89b..00861c328ca0 100644
@@ -2825,6 +2825,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
 	.fem_setup		= NULL,
 	.rfe_gpio		= NULL,
 	.rfk_init		= rtw8852c_rfk_init,
+	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8852c_rfk_channel,
 	.rfk_band_changed	= rtw8852c_rfk_band_changed,
 	.rfk_scan		= rtw8852c_rfk_scan,
drivers/net/wireless/realtek/rtw89/rtw8922a.c +9 -0
index 69ae8f81181e..0cbe4780eb69 100644
@@ -1379,6 +1379,14 @@ static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev)
 	memset(rfk_mcc, 0, sizeof(*rfk_mcc));
 }
 
+static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev)
+{
+	rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);
+
+	rtw89_phy_rfk_dack_and_wait(rtwdev, RTW89_PHY_0, 58);
+	rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, 32);
+}
+
 static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
 {
 	u32 rf_mode;
@@ -1687,6 +1695,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
 	.fem_setup		= NULL,
 	.rfe_gpio		= NULL,
 	.rfk_init		= rtw8922a_rfk_init,
+	.rfk_init_late		= rtw8922a_rfk_init_late,
 	.rfk_channel		= rtw8922a_rfk_channel,
 	.rfk_band_changed	= rtw8922a_rfk_band_changed,
 	.rfk_scan		= rtw8922a_rfk_scan,
Signature · 1 line
2.25.1
author maintainer
#12 lore raw

PATCH 11/11 wifi: rtw89: 8922a: add chip_ops::rfk_hw_init

In reply to Ping-Ke Shih

Add a chip_ops for WiFi 7 chips to set additional RF configurations including MLO and PLL settings.

---
 drivers/net/wireless/realtek/rtw89/core.h     |   9 +
 drivers/net/wireless/realtek/rtw89/mac.h      |   2 +
 drivers/net/wireless/realtek/rtw89/phy.c      |   1 +
 drivers/net/wireless/realtek/rtw89/reg.h      |   6 +
 drivers/net/wireless/realtek/rtw89/rtw8851b.c |   1 +
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |   1 +
 drivers/net/wireless/realtek/rtw89/rtw8852b.c |   1 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c |   1 +
 drivers/net/wireless/realtek/rtw89/rtw8922a.c |   1 +
 .../net/wireless/realtek/rtw89/rtw8922a_rfk.c | 202 ++++++++++++++++++
 .../net/wireless/realtek/rtw89/rtw8922a_rfk.h |   1 +
 11 files changed, 226 insertions(+)
drivers/net/wireless/realtek/rtw89/core.h +9 -0
index 270403f6c3d5..22255e98ab6b 100644
@@ -3156,6 +3156,7 @@ struct rtw89_chip_ops {
 	int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map);
 	void (*fem_setup)(struct rtw89_dev *rtwdev);
 	void (*rfe_gpio)(struct rtw89_dev *rtwdev);
+	void (*rfk_hw_init)(struct rtw89_dev *rtwdev);
 	void (*rfk_init)(struct rtw89_dev *rtwdev);
 	void (*rfk_init_late)(struct rtw89_dev *rtwdev);
 	void (*rfk_channel)(struct rtw89_dev *rtwdev);
@@ -5604,6 +5605,14 @@ static inline void rtw89_chip_rfe_gpio(struct rtw89_dev *rtwdev)
 		chip->ops->rfe_gpio(rtwdev);
 }
 
+static inline void rtw89_chip_rfk_hw_init(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+
+	if (chip->ops->rfk_hw_init)
+		chip->ops->rfk_hw_init(rtwdev);
+}
+
 static inline
 void rtw89_chip_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 {
drivers/net/wireless/realtek/rtw89/mac.h +2 -0
index b3fe4cab6d3a..7aea57804e93 100644
@@ -1328,6 +1328,7 @@ enum rtw89_mac_xtal_si_offset {
 #define XTAL_SI_BIG_PWR_CUT	BIT(1)
 	XTAL_SI_XTAL_DRV = 0x15,
 #define XTAL_SI_DRV_LATCH	BIT(4)
+	XTAL_SI_XTAL_PLL = 0x16,
 	XTAL_SI_XTAL_XMD_2 = 0x24,
 #define XTAL_SI_LDO_LPS		GENMASK(6, 4)
 	XTAL_SI_XTAL_XMD_4 = 0x26,
@@ -1361,6 +1362,7 @@ enum rtw89_mac_xtal_si_offset {
 	XTAL_SI_SRAM_CTRL = 0xA1,
 #define XTAL_SI_SRAM_DIS	BIT(1)
 #define FULL_BIT_MASK		GENMASK(7, 0)
+	XTAL_SI_APBT = 0xD1,
 	XTAL_SI_PLL = 0xE0,
 	XTAL_SI_PLL_1 = 0xE1,
 };
drivers/net/wireless/realtek/rtw89/phy.c +1 -0
index f02b365b0cec..9a8f5b764617 100644
@@ -5874,6 +5874,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
 	rtw89_chip_rfe_gpio(rtwdev);
 	rtw89_phy_antdiv_set_ant(rtwdev);
 
+	rtw89_chip_rfk_hw_init(rtwdev);
 	rtw89_phy_init_rf_nctl(rtwdev);
 	rtw89_chip_rfk_init(rtwdev);
 	rtw89_chip_set_txpwr_ctrl(rtwdev);
drivers/net/wireless/realtek/rtw89/reg.h +6 -0
index 9f209f068679..6368b2b32c0c 100644
@@ -7402,6 +7402,7 @@
 #define RR_MOD_M_RXBB GENMASK(9, 5)
 #define RR_MOD_LO_SEL BIT(1)
 #define RR_MODOPT 0x01
+#define RR_TXG_SEL GENMASK(19, 17)
 #define RR_MODOPT_M_TXPWR GENMASK(5, 0)
 #define RR_WLSEL 0x02
 #define RR_WLSEL_AG GENMASK(18, 16)
@@ -7594,6 +7595,7 @@
 #define RR_MIXER_GN GENMASK(4, 3)
 #define RR_POW 0xa0
 #define RR_POW_SYN GENMASK(3, 2)
+#define RR_POW_SYN_V1 GENMASK(3, 0)
 #define RR_LOGEN 0xa3
 #define RR_LOGEN_RPT GENMASK(19, 16)
 #define RR_SX 0xaf
@@ -8734,6 +8736,8 @@
 #define B_COEF_SEL_IQC BIT(0)
 #define B_COEF_SEL_IQC_V1 GENMASK(1, 0)
 #define B_COEF_SEL_MDPD BIT(8)
+#define B_COEF_SEL_MDPD_V1 GENMASK(9, 8)
+#define B_COEF_SEL_EN BIT(31)
 #define R_CFIR_SYS 0x8120
 #define R_IQK_RES 0x8124
 #define B_IQK_RES_K BIT(28)
@@ -8755,8 +8759,10 @@
 #define B_RFGAIN_BND GENMASK(4, 0)
 #define R_CFIR_MAP 0x8150
 #define R_CFIR_LUT 0x8154
+#define R_CFIR_LUT_C1 0x8254
 #define B_CFIR_LUT_SEL BIT(8)
 #define B_CFIR_LUT_SET BIT(4)
+#define B_CFIR_LUT_G5 BIT(5)
 #define B_CFIR_LUT_G3 BIT(3)
 #define B_CFIR_LUT_G2 BIT(2)
 #define B_CFIR_LUT_GP_V1 GENMASK(2, 0)
drivers/net/wireless/realtek/rtw89/rtw8851b.c +1 -0
index 09e38713bca7..83db0a686ee2 100644
@@ -2310,6 +2310,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
 	.read_phycap		= rtw8851b_read_phycap,
 	.fem_setup		= NULL,
 	.rfe_gpio		= rtw8851b_rfe_gpio,
+	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8851b_rfk_init,
 	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8851b_rfk_channel,
drivers/net/wireless/realtek/rtw89/rtw8852a.c +1 -0
index 01c249dddfb8..8e808ded5d52 100644
@@ -2054,6 +2054,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
 	.read_phycap		= rtw8852a_read_phycap,
 	.fem_setup		= rtw8852a_fem_setup,
 	.rfe_gpio		= NULL,
+	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8852a_rfk_init,
 	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8852a_rfk_channel,
drivers/net/wireless/realtek/rtw89/rtw8852b.c +1 -0
index fb6ad335a37a..19454766f3de 100644
@@ -2479,6 +2479,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
 	.read_phycap		= rtw8852b_read_phycap,
 	.fem_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8852b_rfk_init,
 	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8852b_rfk_channel,
drivers/net/wireless/realtek/rtw89/rtw8852c.c +1 -0
index 00861c328ca0..ca8547fbd70e 100644
@@ -2824,6 +2824,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
 	.read_phycap		= rtw8852c_read_phycap,
 	.fem_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8852c_rfk_init,
 	.rfk_init_late		= NULL,
 	.rfk_channel		= rtw8852c_rfk_channel,
drivers/net/wireless/realtek/rtw89/rtw8922a.c +1 -0
index 0cbe4780eb69..6dc051934b0f 100644
@@ -1694,6 +1694,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
 	.read_phycap		= rtw8922a_read_phycap,
 	.fem_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.rfk_hw_init		= rtw8922a_rfk_hw_init,
 	.rfk_init		= rtw8922a_rfk_init,
 	.rfk_init_late		= rtw8922a_rfk_init_late,
 	.rfk_channel		= rtw8922a_rfk_channel,
drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c +202 -0

212 lines not on this page · raw message

drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.h +1 -0
index fbd22de269e2..de5fa6c74530 100644
@@ -8,5 +8,6 @@
 #include "core.h"
 
 void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx);
+void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev);
 
 #endif
Signature · 1 line
2.25.1