From: Ho Jie Feng <hjf3108@gmail.com>
To: Ping-Ke Shih <pkshih@realtek.com>
Cc: linux-wireless@vger.kernel.org, Ho Jie Feng <hjf3108@gmail.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 3/6] wifi: rtw88: prepare frequency-offset correction for more chips
Date: Thu, 29 Oct 2026 13:52:05 +0800 [thread overview]
Message-ID: <20261029055212.84711-4-hjf3108@gmail.com> (raw)
In-Reply-To: <20261029055212.84711-1-hjf3108@gmail.com>
Promote chip specific functions into the common core for cfo tracking.
These become helpers which can be used by the other drivers.
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
drivers/net/wireless/realtek/rtw88/phy.c | 106 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/phy.h | 2 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 100 +----------------
drivers/net/wireless/realtek/rtw88/rtw8822c.h | 3 -
4 files changed, 113 insertions(+), 98 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index e2515a662bb30..d0c1fb65be956 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -720,6 +720,112 @@ void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev,
}
EXPORT_SYMBOL(rtw_phy_parsing_cfo);
+#define CFO_TRK_ENABLE_TH 20
+#define CFO_TRK_STOP_TH 10
+#define CFO_TRK_ADJ_TH 10
+
+static u8 rtw_phy_cfo_tracking_reset(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+
+ cfo->is_adjust = true;
+
+ if (cfo->crystal_cap > rtwdev->efuse.crystal_cap)
+ return cfo->crystal_cap - 1;
+ else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap)
+ return cfo->crystal_cap + 1;
+
+ return cfo->crystal_cap;
+}
+
+void rtw_phy_cfo_xcap_init(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+
+ cfo->crystal_cap = rtwdev->efuse.crystal_cap;
+ cfo->is_adjust = true;
+}
+EXPORT_SYMBOL(rtw_phy_cfo_xcap_init);
+
+#define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); })
+static s32 rtw_phy_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+ s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum;
+ u8 i;
+
+ for (i = 0; i < path_num; i++) {
+ cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]);
+
+ if (cfo->cfo_cnt[i])
+ cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i];
+ else
+ cfo_avg = 0;
+
+ cfo_path_sum += cfo_avg;
+ }
+
+ for (i = 0; i < path_num; i++) {
+ cfo->cfo_tail[i] = 0;
+ cfo->cfo_cnt[i] = 0;
+ }
+
+ return cfo_path_sum / path_num;
+}
+
+static void rtw_phy_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+
+ if (!cfo->is_adjust) {
+ if (abs(cfo_avg) > CFO_TRK_ENABLE_TH)
+ cfo->is_adjust = true;
+ } else {
+ if (abs(cfo_avg) <= CFO_TRK_STOP_TH)
+ cfo->is_adjust = false;
+ }
+}
+
+u8 rtw_phy_cfo_xcap_track(struct rtw_dev *rtwdev, u8 xcap_max, bool bt_hold)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_cfo_track *cfo = &dm_info->cfo_track;
+ u8 path_num = rtwdev->hal.rf_path_num;
+ s8 crystal_cap = cfo->crystal_cap;
+ s32 cfo_avg = 0;
+
+ if (rtwdev->sta_cnt != 1)
+ return rtw_phy_cfo_tracking_reset(rtwdev);
+
+ if (cfo->packet_count == cfo->packet_count_pre)
+ return cfo->crystal_cap;
+
+ cfo->packet_count_pre = cfo->packet_count;
+ cfo_avg = rtw_phy_cfo_calc_avg(rtwdev, path_num);
+ rtw_phy_cfo_need_adjust(rtwdev, cfo_avg);
+
+ if (bt_hold) {
+ cfo->is_adjust = false;
+ return rtwdev->efuse.crystal_cap;
+ }
+
+ if (cfo->is_adjust) {
+ if (cfo_avg > CFO_TRK_ADJ_TH)
+ crystal_cap++;
+ else if (cfo_avg < -CFO_TRK_ADJ_TH)
+ crystal_cap--;
+
+ crystal_cap = clamp_t(s8, crystal_cap, 0, xcap_max);
+ }
+
+ return (u8)crystal_cap;
+}
+EXPORT_SYMBOL(rtw_phy_cfo_xcap_track);
+
static void rtw_phy_cfo_track(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h
index 8a843aac7350a..b551cb860d625 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.h
+++ b/drivers/net/wireless/realtek/rtw88/phy.h
@@ -68,6 +68,8 @@ void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev);
void rtw_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl);
void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev,
struct rtw_rx_pkt_stat *pkt_stat);
+void rtw_phy_cfo_xcap_init(struct rtw_dev *rtwdev);
+u8 rtw_phy_cfo_xcap_track(struct rtw_dev *rtwdev, u8 xcap_max, bool bt_hold);
void rtw_phy_tx_path_diversity(struct rtw_dev *rtwdev);
struct rtw_txpwr_lmt_cfg_pair {
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 32d9709f2c243..54f012a238391 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4243,103 +4243,13 @@ static void rtw8822c_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap)
rtw8822c_set_crystal_cap_reg(rtwdev, crystal_cap);
}
-static void rtw8822c_cfo_tracking_reset(struct rtw_dev *rtwdev)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
-
- cfo->is_adjust = true;
-
- if (cfo->crystal_cap > rtwdev->efuse.crystal_cap)
- rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap - 1);
- else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap)
- rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap + 1);
-}
-
-static void rtw8822c_cfo_init(struct rtw_dev *rtwdev)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
-
- cfo->crystal_cap = rtwdev->efuse.crystal_cap;
- cfo->is_adjust = true;
-}
-
-#define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); })
-static s32 rtw8822c_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
- s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum;
- u8 i;
-
- for (i = 0; i < path_num; i++) {
- cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]);
-
- if (cfo->cfo_cnt[i])
- cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i];
- else
- cfo_avg = 0;
-
- cfo_path_sum += cfo_avg;
- }
-
- for (i = 0; i < path_num; i++) {
- cfo->cfo_tail[i] = 0;
- cfo->cfo_cnt[i] = 0;
- }
-
- return cfo_path_sum / path_num;
-}
-
-static void rtw8822c_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg)
-{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
-
- if (!cfo->is_adjust) {
- if (abs(cfo_avg) > CFO_TRK_ENABLE_TH)
- cfo->is_adjust = true;
- } else {
- if (abs(cfo_avg) <= CFO_TRK_STOP_TH)
- cfo->is_adjust = false;
- }
-
- if (!rtw_coex_disabled(rtwdev)) {
- cfo->is_adjust = false;
- rtw8822c_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap);
- }
-}
-
static void rtw8822c_cfo_track(struct rtw_dev *rtwdev)
{
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
- struct rtw_cfo_track *cfo = &dm_info->cfo_track;
- u8 path_num = rtwdev->hal.rf_path_num;
- s8 crystal_cap = cfo->crystal_cap;
- s32 cfo_avg = 0;
-
- if (rtwdev->sta_cnt != 1) {
- rtw8822c_cfo_tracking_reset(rtwdev);
- return;
- }
-
- if (cfo->packet_count == cfo->packet_count_pre)
- return;
-
- cfo->packet_count_pre = cfo->packet_count;
- cfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num);
- rtw8822c_cfo_need_adjust(rtwdev, cfo_avg);
-
- if (cfo->is_adjust) {
- if (cfo_avg > CFO_TRK_ADJ_TH)
- crystal_cap++;
- else if (cfo_avg < -CFO_TRK_ADJ_TH)
- crystal_cap--;
+ u8 crystal_cap;
- crystal_cap = clamp_t(s8, crystal_cap, 0, XCAP_MASK);
- rtw8822c_set_crystal_cap(rtwdev, (u8)crystal_cap);
- }
+ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, XCAP_MASK,
+ !rtw_coex_disabled(rtwdev));
+ rtw8822c_set_crystal_cap(rtwdev, crystal_cap);
}
static const struct rtw_phy_cck_pd_reg
@@ -4985,7 +4895,7 @@ static const struct rtw_chip_ops rtw8822c_ops = {
.cfg_csi_rate = rtw_bf_cfg_csi_rate,
.adaptivity_init = rtw8822c_adaptivity_init,
.adaptivity = rtw8822c_adaptivity,
- .cfo_init = rtw8822c_cfo_init,
+ .cfo_init = rtw_phy_cfo_xcap_init,
.cfo_track = rtw8822c_cfo_track,
.config_tx_path = rtw8822c_config_tx_path,
.config_txrx_mode = rtw8822c_config_trx_mode,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
index fc62b67a15f21..c27e4c394a435 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
@@ -181,9 +181,6 @@ const struct rtw_table name ## _tbl = { \
#define REG_ANAPARLDO_POW_MAC 0x0029
#define BIT_LDOE25_PON BIT(0)
#define XCAP_MASK GENMASK(6, 0)
-#define CFO_TRK_ENABLE_TH 20
-#define CFO_TRK_STOP_TH 10
-#define CFO_TRK_ADJ_TH 10
#define REG_TXDFIR0 0x808
#define REG_DFIRBW 0x810
--
2.55.0
next prev parent reply other threads:[~2026-10-29 5:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 5:52 [PATCH 0/6] wifi: rtw88: extend 88xxA support Ho Jie Feng
2026-10-29 5:52 ` [PATCH 1/6] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
2026-10-29 5:52 ` [PATCH 2/6] wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions Ho Jie Feng
2026-10-29 5:52 ` Ho Jie Feng [this message]
2026-10-29 5:52 ` [PATCH 4/6] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
2026-10-29 5:52 ` [PATCH 5/6] wifi: rtw88: 88xxa: adapt channel sensing to receiver gain Ho Jie Feng
2026-10-29 5:52 ` [PATCH 6/6] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits Ho Jie Feng
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=20261029055212.84711-4-hjf3108@gmail.com \
--to=hjf3108@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=pkshih@realtek.com \
/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