From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
To: linux-wireless@vger.kernel.org
Subject: Re: [PATCH rtw-next v2 6/7] wifi: rtw88: 88xxa: adapt channel sensing to receiver gain
Date: Tue, 3 Nov 2026 19:41:32 +0200 [thread overview]
Message-ID: <08bfa108-3e8a-40fb-a901-99031b284236@gmail.com> (raw)
In-Reply-To: <20261031070950.425176-7-hjf3108@gmail.com>
On 31/10/2026 09:09, Ho Jie Feng wrote:
> Implement adaptivity for 88xxa, since they support it in
> the hardware.
>
> Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
This version doesn't have the high latency during scans anymore.
However, the message "firmware failed to leave lps state" appears
a lot more often now. It stops if I disable EDCCA.
> ---
> drivers/net/wireless/realtek/rtw88/main.h | 1 +
> drivers/net/wireless/realtek/rtw88/phy.c | 7 +
> drivers/net/wireless/realtek/rtw88/rtw8812a.c | 10 ++
> drivers/net/wireless/realtek/rtw88/rtw8821a.c | 10 ++
> drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 125 ++++++++++++++++++
> drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 5 +
> 6 files changed, 158 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
> index d59f6e323adf0c9bf9aeab7a62adb77e3e5f9d74..796fea308fdf7bf2b46f42c703b1b518327e1e0a 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.h
> +++ b/drivers/net/wireless/realtek/rtw88/main.h
> @@ -1787,6 +1787,7 @@ struct rtw_dm_info {
> bool is_bt_iqk_timeout;
>
> s8 l2h_th_ini;
> + s8 l2h_th_lb;
> enum rtw_edcca_mode edcca_mode;
> u8 scan_density;
> };
> diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
> index 69998c0d7c1f851bb30d2702233d62e14b305bf0..7a04aec9a045f1e308a4c5d331c900e013996bd5 100644
> --- a/drivers/net/wireless/realtek/rtw88/phy.c
> +++ b/drivers/net/wireless/realtek/rtw88/phy.c
> @@ -377,6 +377,10 @@ void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev)
> DIG_CVRG_MIN);
>
> rtw_phy_dig_write(rtwdev, DIG_CVRG_MIN);
> +
> + /* EDCCA thresholds can be relative to the IGI */
> + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_ADAPTIVITY))
> + rtw_phy_adaptivity(rtwdev);
> }
>
> void rtw_phy_dig_reset(struct rtw_dev *rtwdev)
> @@ -388,6 +392,9 @@ void rtw_phy_dig_reset(struct rtw_dev *rtwdev)
> rtw_dbg(rtwdev, RTW_DBG_PHY, "Resetting IGI=%#x\n", last_igi);
>
> rtw_phy_dig_write(rtwdev, last_igi);
> +
> + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_ADAPTIVITY))
> + rtw_phy_adaptivity(rtwdev);
> }
>
> static bool
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> index c8008cf43da9df68a8c1dfb277d529a1191bda01..d93c4776e0303f52273d92eaa75341ebbcfcb066 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> @@ -945,6 +945,8 @@ static const struct rtw_chip_ops rtw8812a_ops = {
> .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,
> .cfo_init = rtw_phy_cfo_xcap_init,
> .cfo_track = rtw88xxa_cfo_track,
> + .adaptivity_init = rtw88xxa_adaptivity_init,
> + .adaptivity = rtw88xxa_adaptivity,
> };
>
> static const struct rtw_page_table page_table_8812a[] = {
> @@ -999,6 +1001,11 @@ static const struct rtw_hw_reg rtw8812a_dig[] = {
> [1] = { .addr = REG_RXIGI_B, .mask = 0x7f },
> };
>
> +static const struct rtw_hw_reg_offset rtw8812a_edcca_th[] = {
> + [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
> + [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
> +};
> +
> static const struct rtw_rfe_def rtw8812a_rfe_defs[] = {
> [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl,
> .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,
> @@ -1089,6 +1096,9 @@ const struct rtw_chip_info rtw8812a_hw_spec = {
> .bfer_su_max_num = 2,
> .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
> .max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
> + .edcca_th = rtw8812a_edcca_th,
> + .l2h_th_ini_cs = 10,
> + .l2h_th_ini_ad = -17,
>
> .coex_para_ver = 0, /* no coex code in 8812au driver */
> .bt_desired_ver = 0,
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> index 17d3677ca463cf633d8c138612deaa676bc02986..f7391f6aa3039c7ba4d88249d968a5f1763ea866 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> @@ -891,6 +891,8 @@ static const struct rtw_chip_ops rtw8821a_ops = {
> .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,
> .cfo_init = rtw_phy_cfo_xcap_init,
> .cfo_track = rtw88xxa_cfo_track,
> + .adaptivity_init = rtw88xxa_adaptivity_init,
> + .adaptivity = rtw88xxa_adaptivity,
> };
>
> static const struct rtw_page_table page_table_8821a[] = {
> @@ -944,6 +946,11 @@ static const struct rtw_hw_reg rtw8821a_dig[] = {
> [0] = { .addr = REG_RXIGI_A, .mask = 0x7f },
> };
>
> +static const struct rtw_hw_reg_offset rtw8821a_edcca_th[] = {
> + [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
> + [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
> +};
> +
> static const struct rtw_rfe_def rtw8821a_rfe_defs[] = {
> [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl,
> .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl,
> @@ -1193,6 +1200,9 @@ const struct rtw_chip_info rtw8821a_hw_spec = {
> .bfer_su_max_num = 2,
> .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
> .max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
> + .edcca_th = rtw8821a_edcca_th,
> + .l2h_th_ini_cs = 10,
> + .l2h_th_ini_ad = -17,
>
> .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */
> .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
> index 851d198f76f3b10d5ba77c7e07e4be9d7fd54e4b..ee72380757721dab7dc409aabc24b2b825969465 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c
> @@ -2040,6 +2040,131 @@ void rtw88xxa_cfo_track(struct rtw_dev *rtwdev)
> }
> EXPORT_SYMBOL(rtw88xxa_cfo_track);
>
> +#define EDCCA_TH_MAX_88XXA 0x7f
> +#define EDCCA_L2H_CAP_88XXA 10
> +#define EDCCA_L2H_INI_NORMAL_88XXA 20
> +#define EDCCA_DBG_PORT_88XXA 0x209
> +#define EDCCA_DC_BACKOFF_88XXA 2
> +#define EDCCA_LB_START_88XXA (EDCCA_L2H_H2L_DIFF - 30)
> +#define EDCCA_LB_RETRY_88XXA (EDCCA_LB_START_88XXA + 18)
> +
> +static void rtw88xxa_set_rf_mode_rx(struct rtw_dev *rtwdev, u32 data0,
> + u32 data1)
> +{
> + u8 path;
> +
> + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
> + rtw_write_rf(rtwdev, path, RF_LUTWE, BIT(19), 1);
> + rtw_write_rf(rtwdev, path, RF_MODE_TABLE_ADDR, RFREG_MASK,
> + 0x18000);
> + rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA0, RFREG_MASK,
> + data0);
> + rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA1, RFREG_MASK,
> + data1);
> + rtw_write_rf(rtwdev, path, RF_LUTWE, BIT(19), 0);
> + }
> +}
> +
> +static void rtw88xxa_set_lna(struct rtw_dev *rtwdev, bool enable)
> +{
> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
> + rtw88xxa_set_rf_mode_rx(rtwdev, 0x3f7ff,
> + enable ? 0xc26bf : 0xc22bf);
> + else
> + rtw88xxa_set_rf_mode_rx(rtwdev, 0x0002f,
> + enable ? 0xfb0bb : 0xfb09b);
> +}
> +
> +static u8 rtw88xxa_edcca_count(struct rtw_dev *rtwdev)
> +{
> + u8 cnt = 0;
> + int i;
> +
> + rtw_write32(rtwdev, REG_DBGSEL, 0);
> + for (i = 0; i < 3 &&
> + rtw_read32(rtwdev, REG_DBGRPT) & BIT_DBG_CCA_BUSY; i++)
> + usleep_range(3000, 3500);
> +
> + rtw_write32(rtwdev, REG_DBGSEL, EDCCA_DBG_PORT_88XXA);
> + for (i = 0; i < 20; i++)
> + if (rtw_read32(rtwdev, REG_DBGRPT) & BIT_DBG_EDCCA_BUSY)
> + cnt++;
> +
> + return cnt;
> +}
> +
> +static s8 rtw88xxa_edcca_search_floor(struct rtw_dev *rtwdev)
> +{
> + s8 l2h = EDCCA_LB_START_88XXA;
> +
> + rtw_phy_set_edcca_th(rtwdev, l2h, l2h - EDCCA_L2H_H2L_DIFF);
> + msleep(30);
> +
> + while (l2h < EDCCA_L2H_CAP_88XXA && rtw88xxa_edcca_count(rtwdev) > 1) {
> + l2h++;
> + rtw_phy_set_edcca_th(rtwdev, l2h, l2h - EDCCA_L2H_H2L_DIFF);
> + }
> +
> + return l2h;
> +}
> +
> +void rtw88xxa_adaptivity_init(struct rtw_dev *rtwdev)
> +{
> + struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> + u32 dbgsel = rtw_read32(rtwdev, REG_DBGSEL);
> + s8 l2h;
> +
> + rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
> +
> + rtw88xxa_set_lna(rtwdev, false);
> + l2h = rtw88xxa_edcca_search_floor(rtwdev);
> + if (l2h >= EDCCA_LB_RETRY_88XXA)
> + l2h = rtw88xxa_edcca_search_floor(rtwdev);
> + rtw88xxa_set_lna(rtwdev, true);
> + rtw_write32(rtwdev, REG_DBGSEL, dbgsel);
> +
> + dm_info->l2h_th_lb = l2h + EDCCA_DC_BACKOFF_88XXA;
> + rtw_phy_set_edcca_th(rtwdev, EDCCA_TH_MAX_88XXA, EDCCA_TH_MAX_88XXA);
> +
> + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "EDCCA L2H floor %d\n",
> + dm_info->l2h_th_lb);
> +}
> +EXPORT_SYMBOL(rtw88xxa_adaptivity_init);
> +
> +void rtw88xxa_adaptivity(struct rtw_dev *rtwdev)
> +{
> + struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> + /* igi_history[0] keeps the pre-scan IGI while scanning */
> + u8 igi = rtw_read32_mask(rtwdev, REG_RXIGI_A, 0x7f);
> + int igi_diff = EDCCA_IGI_BASE - igi;
> + s8 l2h_lb = dm_info->l2h_th_lb;
> + s8 l2h, h2l;
> +
> + /* toggle the ADC mask to work around an EDCCA hang */
> + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) {
> + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT(10));
> + rtw_write32_clr(rtwdev, REG_FPGA0_RFMOD, BIT(10));
> + }
> +
> + if (dm_info->edcca_mode == RTW_EDCCA_ADAPTIVITY) {
> + l2h = min(dm_info->l2h_th_ini + igi_diff, EDCCA_L2H_CAP_88XXA);
> + h2l = l2h - EDCCA_L2H_H2L_DIFF;
> + } else {
> + l2h = EDCCA_L2H_INI_NORMAL_88XXA + igi_diff;
> + h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
> + }
> +
> + l2h = max(l2h, l2h_lb);
> + h2l = max_t(s8, h2l, l2h_lb - EDCCA_L2H_H2L_DIFF);
> +
> + rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
> +
> + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
> + "EDCCA mode %d, IGI 0x%x, L2H %d, H2L %d\n",
> + dm_info->edcca_mode, igi, l2h, h2l);
> +}
> +EXPORT_SYMBOL(rtw88xxa_adaptivity);
> +
> MODULE_AUTHOR("Realtek Corporation");
> MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code");
> MODULE_LICENSE("Dual BSD/GPL");
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
> index 09b72d33f62e1e99a2ac5af23ac1630dabb38ef9..b8719c278df7326842e09509fc52d12f226fd417 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
> +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h
> @@ -139,6 +139,9 @@ struct rtw_jaguar_phy_status_rpt {
>
> #define RF18_BW_MASK (BIT(11) | BIT(10))
>
> +#define BIT_DBG_CCA_BUSY BIT(3)
> +#define BIT_DBG_EDCCA_BUSY BIT(29)
> +
> void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on);
> int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map);
> void rtw88xxa_power_off(struct rtw_dev *rtwdev,
> @@ -173,5 +176,7 @@ void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
> void rtw88xxa_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
> struct rtw_bfee *bfee, bool enable);
> void rtw88xxa_cfo_track(struct rtw_dev *rtwdev);
> +void rtw88xxa_adaptivity_init(struct rtw_dev *rtwdev);
> +void rtw88xxa_adaptivity(struct rtw_dev *rtwdev);
>
> #endif
next prev parent reply other threads:[~2026-11-03 17:41 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-31 7:09 [PATCH rtw-next v2 0/7] wifi: rtw88: extend 88xxA support Ho Jie Feng
2026-10-31 7:09 ` [PATCH rtw-next v2 1/7] wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions Ho Jie Feng
2026-11-06 17:21 ` Luka Gejak
2026-10-31 7:09 ` [PATCH rtw-next v2 2/7] wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions Ho Jie Feng
2026-11-03 16:36 ` Bitterblue Smith
2026-11-06 17:23 ` Luka Gejak
2026-10-31 7:09 ` [PATCH rtw-next v2 3/7] wifi: rtw88: correctly expose beamformee capabilities Ho Jie Feng
2026-11-06 17:25 ` Luka Gejak
2026-10-31 7:09 ` [PATCH rtw-next v2 4/7] wifi: rtw88: prepare frequency-offset correction for more chips Ho Jie Feng
2026-10-31 7:09 ` [PATCH rtw-next v2 5/7] wifi: rtw88: 88xxa: correct carrier-frequency offset Ho Jie Feng
2026-11-06 17:27 ` Luka Gejak
2026-11-06 20:03 ` Bitterblue Smith
2026-11-09 13:39 ` Ho Jie Feng
2026-11-10 8:03 ` Luka Gejak
2026-10-31 7:09 ` [PATCH rtw-next v2 6/7] wifi: rtw88: 88xxa: adapt channel sensing to receiver gain Ho Jie Feng
2026-11-03 17:41 ` Bitterblue Smith [this message]
2026-11-04 12:47 ` Ho Jie Feng
2026-11-06 17:34 ` Luka Gejak
2026-11-06 19:46 ` Bitterblue Smith
2026-11-06 20:27 ` Luka Gejak
2026-11-10 14:36 ` Bitterblue Smith
2026-11-10 19:57 ` Luka Gejak
2026-10-31 7:09 ` [PATCH rtw-next v2 7/7] wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits Ho Jie Feng
2026-11-06 17:35 ` Luka Gejak
2026-11-08 18:09 ` Jie Feng
2026-11-09 7:25 ` Luka Gejak
2026-11-06 17:44 ` [PATCH rtw-next v2 0/7] wifi: rtw88: extend 88xxA support Luka Gejak
2026-11-08 18:10 ` 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=08bfa108-3e8a-40fb-a901-99031b284236@gmail.com \
--to=rtl8821cerfe2@gmail.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;
as well as URLs for NNTP newsgroup(s).