Linux wireless drivers development
 help / color / mirror / Atom feed
From: Ping-Ke Shih <pkshih@realtek.com>
To: <linux-wireless@vger.kernel.org>
Cc: <ku920601@realtek.com>
Subject: [PATCH rtw-next 08/11] wifi: rtw89: coex: Correct SET_RFE settings
Date: Sun, 12 Jul 2026 11:05:03 +0800	[thread overview]
Message-ID: <20260712030506.43438-9-pkshih@realtek.com> (raw)
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>

From: Ching-Te Ku <ku920601@realtek.com>

Because of dual-BT & dual-MAC, RTL8922D has more complex antenna settings.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/coex.h     |  31 +++
 drivers/net/wireless/realtek/rtw89/core.h     |  11 +
 drivers/net/wireless/realtek/rtw89/rtw8922d.c | 213 ++++++++++++++++--
 3 files changed, 231 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index fdd63e2c0837..e17407696d8a 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -143,6 +143,11 @@ enum btc_switch {
 	BTC_SWITCH_EXTERNAL
 };
 
+enum btc_ant_switch_type {
+	BTC_SWITCH_V1_NONE = 0, /* independent antenna */
+	BTC_SWITCH_V1_INTERNAL, /* internal-switch: BTGA structure */
+};
+
 enum btc_pkt_type {
 	PACKET_DHCP,
 	PACKET_ARP,
@@ -262,6 +267,32 @@ enum btc_chip_feature {
 	BTC_FEAT_DUAL_BTGA = BIT(9) /* the future A-Die */
 };
 
+enum btc_efuse_ant_function_map {
+	BTC_EFMAP_NONE = 0,
+	BTC_EFMAP_BT0 = BIT(0),
+	BTC_EFMAP_BT1 = BIT(1),
+	BTC_EFMAP_ZB = BIT(2), /* ZB or thread */
+	BTC_EFMAP_24GP = BIT(3),
+	BTC_EFMAP_ULL = BIT(4),
+};
+
+enum btc_extsoc_interface { /* cx->other.hw_coex */
+	BTC_EXTSOC_INTF_NONE = 0,
+	BTC_EXTSOC_INTF_PTA = BIT(0),
+	BTC_EXTSOC_INTF_MBX = BIT(1),
+	BTC_EXTSOC_INTF_SWIO = BIT(2),
+	BTC_EXTSOC_INTF_MAX,
+};
+
+enum btc_esoc_type {
+	BTC_ESOC_NONE,
+	BTC_ESOC_8761,
+	BTC_ESOC_8771,
+	BTC_ESOC_SILAB_MG21,
+	BTC_ESOC_NORDI_NRF52840,
+	BTC_ESOC_MAX,
+};
+
 enum btc_wl_mode {
 	BTC_WL_MODE_11B = 0,
 	BTC_WL_MODE_11A = 1,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index f784e8437292..d876de21482f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2434,6 +2434,15 @@ struct rtw89_btc_wl_tx_limit_para {
 	u16 tx_retry;
 };
 
+struct rtw89_btc_wl_trx_nss_para {
+	u8 tx_limit;
+	u8 rx_limit;
+	u8 tx_ss;
+	u8 rx_ss;
+	u8 tx_path;
+	u8 rx_path;
+};
+
 enum rtw89_btc_bt_scan_type {
 	BTC_SCAN_INQ	= 0,
 	BTC_SCAN_PAGE,
@@ -3616,6 +3625,7 @@ struct rtw89_btc_dm {
 	struct rtw89_btc_bind_info fdd_bind;
 	struct rtw89_btc_fddt_info fddt_info;
 	struct rtw89_btc_fddr_info fddr_info;
+	struct rtw89_btc_wl_trx_nss_para wl_trx_nss;
 	u32 cnt_dm[BTC_DCNT_NUM];
 	u32 cnt_notify[BTC_NCNT_NUM];
 	u8 ant_xmap[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT ANT interact-map */
@@ -3664,6 +3674,7 @@ struct rtw89_btc_dm {
 	u8 wl_tx_pwr_phy_map;
 	u8 vid;
 	u8 client_ps_tdma_on;
+	u8 wl_trx_nss_en;
 
 	u8 wl_pre_agc: 2;
 	u8 wl_lna2: 1;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index aeade858ce95..c28670e82c3e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -3106,46 +3106,211 @@ static u32 rtw8922d_chan_to_rf18_val(struct rtw89_dev *rtwdev,
 
 static void rtw8922d_btc_set_rfe(struct rtw89_dev *rtwdev)
 {
+	struct rtw89_btc *btc = &rtwdev->btc;
+	struct rtw89_btc_dm *dm = &btc->dm;
+	struct rtw89_btc_cx *cx = &btc->cx;
 	union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
-	struct rtw89_btc_module_v7 *module = &md->md_v7;
+	struct rtw89_btc_module_v10 *module = &md->md_v10;
+	u8 efuse_bt_func, efuse_ant_info, bt_sw_gpio_pos;
+	u8 is_combo, is_bt_share;
 
+	rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s !!\n", __func__);
+
+	/* get from final capability of device */
 	module->rfe_type = rtwdev->efuse.rfe_type;
 	module->kt_ver = rtwdev->hal.cv;
-	module->bt_solo = 0;
-	module->switch_type = BTC_SWITCH_INTERNAL;
+	module->kt_ver_adie = rtwdev->hal.acv;
 	module->wa_type = 0;
+	dm->wl_trx_nss_en = 0;
 
-	module->ant.type = BTC_ANT_SHARED;
 	module->ant.num = 2;
-	module->ant.isolation = 10;
-	module->ant.diversity = 0;
-	module->ant.single_pos = RF_PATH_A;
-	module->ant.btg_pos = RF_PATH_B;
+	module->ant.single_pos = BTC_RF_S0; /* WL 1ss+1Ant 0:s0(A)/ 1:s1(B) */
 
-	if (module->kt_ver <= 1)
-		module->wa_type |= BTC_WA_HFP_ZB;
+	/* set default antenna isolation */
+	cx->bt0.ant_iso_to_wl = module->ant.isolation;
+	cx->bt1.ant_iso_to_wl = module->ant.isolation;
 
-	rtwdev->btc.cx.bt_ext.func_type = BTC_3CX_NONE;
+	module->ant.stream_cnt = 2;
+	module->ant.btg_pos = BTC_RF_S1; /* BTG0 at WL-S1 */
+	module->ant.btg1_pos = BTC_RF_S0; /* BTG1 at WL-S0 if Dual-BTGA */
 
-	if (module->rfe_type == 0) {
-		rtwdev->btc.dm.error.map.rfe_type0 = true;
-		return;
+	cx->bt0.band_56G_support = 1;
+	cx->bt1.band_56G_support = 1;
+	cx->bt0.func_type = BTC_BTF_BT;
+	cx->bt1.func_type = BTC_BTF_BT;
+
+	efuse_bt_func = rtwdev->efuse.bt_setting_2;
+
+	switch ((efuse_bt_func & 0xe0) >> 5) { /* 0xcd[7:5] */
+	default:
+	case 0:
+	case 1:
+		bt_sw_gpio_pos = 5;
+		break;
+	case 2:
+		bt_sw_gpio_pos = 11;
+		break;
+	case 3:
+		bt_sw_gpio_pos = 15;
+		break;
+	case 4:
+		bt_sw_gpio_pos = 20;
+		break;
 	}
 
-	module->ant.num = (module->rfe_type % 2) ?  2 : 3;
+	efuse_bt_func &= 0x1f; /* 0xcd[4:0] */
+	efuse_ant_info = rtwdev->efuse.bt_setting_3;
+	module->ant.num = (efuse_ant_info & 0xe0) >> 5; /* 0xCE[7:5] */
+	is_combo = (efuse_ant_info & 0xe) >> 1; /* 0xCE[3:1] */
+	is_bt_share = efuse_ant_info & BIT(0); /* 0xCE[0] */
 
-	if (module->kt_ver == 0)
-		module->ant.num = 2;
+	memset(dm->ant_xmap, 0, sizeof(dm->ant_xmap));
 
-	if (module->ant.num == 3) {
-		module->ant.type = BTC_ANT_DEDICATED;
-		module->bt_pos = BTC_BT_ALONE;
-	} else {
+	/* To-Do: "RFE_TYpe" to "ant.num" translation */
+	switch (module->ant.num) {
+	case 1: /* 1-Ant WL-S0 only & BT0 only */
 		module->ant.type = BTC_ANT_SHARED;
-		module->bt_pos = BTC_BT_BTG;
+		module->bt0_pos = BTC_BT_BTG;
+		module->bt0_sw_type = BTC_SWITCH_INTERNAL;
+		module->ant.btg_pos = BTC_RF_S0; /* BTG0 at WL-S0 */
+		module->ant.stream_cnt = 1;
+		module->ant.func[0] = BTC_EFMAP_BT0;
+		dm->ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 1; /* BT0 shared with S0*/
+		dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 0; /* WL 1T1R no RF-S1 */
+		break;
+	case 2: /* 2-Ant */
+	default:
+		if (is_combo) {
+			if (efuse_bt_func == (BTC_EFMAP_BT0 | BTC_EFMAP_BT1))
+				module->ant.func[0] = BTC_EFMAP_BT1;
+
+			module->ant.func[1] = BTC_EFMAP_BT0;
+		} else {
+			module->ant.func[0] = BTC_EFMAP_NONE;
+			module->ant.func[1] = BTC_EFMAP_NONE;
+		}
+
+		if (is_bt_share) { /* WL-S0 + (WL-S1 & BT0-S1) */
+			module->ant.type = BTC_ANT_SHARED;
+			module->bt0_pos = BTC_BT_BTG;
+			module->bt0_sw_type = BTC_SWITCH_INTERNAL;
+			dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1;
+		} else { /* WL-S0 + BT0-S1 */
+			module->ant.type = BTC_ANT_DEDICATED;
+			module->bt0_pos = BTC_BT_ALONE;
+			module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+		}
+
+		if (module->ant.func[0] == BTC_EFMAP_BT1) { /* if 2nd BT exist */
+			dm->ant_xmap[BTC_RF_S0][BTC_BT_2ND] = 1;
+			if (module->rfe_type == 12) { /* WL-S0 & BT1 by SPDT */
+				module->bt1_pos = BTC_BT_ALONE;
+				/* Todo: set SPDT GPIO-ctrl */
+				module->bt1_sw_type = bt_sw_gpio_pos;
+			} else { /* WL-S0 & BT1-S1 by BTGA */
+				module->bt1_pos = BTC_BT_BTG;
+				module->bt1_sw_type = BTC_SWITCH_INTERNAL;
+			}
+		}
+
+		dm->wl_trx_nss_en = 1; /* 1ss MIMO-PS capability if 1-BT */
+		break;
+	case 3: /* 3-Ant, 3 different BT-configuration */
+		if (is_bt_share) {
+			module->ant.func[0] = BTC_EFMAP_NONE;
+			module->ant.func[1] = BTC_EFMAP_BT0;
+			module->ant.func[2] = efuse_bt_func & (~BTC_EFMAP_BT0);
+			module->ant.type = BTC_ANT_SHARED;
+			module->bt0_pos = BTC_BT_BTG;
+			module->bt0_sw_type = BTC_SWITCH_INTERNAL;
+			dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1;
+			dm->wl_trx_nss_en = 1; /* 1ss MIMO-PS capability */
+		} else {
+			module->ant.func[0] = BTC_EFMAP_NONE;
+			module->ant.func[1] = BTC_EFMAP_NONE;
+			module->ant.func[2] = efuse_bt_func;
+			module->ant.type = BTC_ANT_DEDICATED;
+			module->bt0_pos = BTC_BT_ALONE;
+			module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+		}
+
+		module->bt1_pos = BTC_BT_ALONE; /* BT1 may exist or not */
+		module->bt1_sw_type = BTC_SWITCH_V1_NONE;
+		break;
+	case 4: /* 4-Ant,  WL-S0 + WL-S1 + BT0 + BT1 */
+		module->ant.func[0] = BTC_EFMAP_NONE;
+		module->ant.func[1] = BTC_EFMAP_NONE;
+		module->ant.func[2] = BTC_EFMAP_BT0;
+		module->ant.func[3] = efuse_bt_func & (~BTC_EFMAP_BT0);
+		module->ant.type = BTC_ANT_DEDICATED;
+		module->bt0_pos = BTC_BT_ALONE;
+		module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+		module->bt1_pos = BTC_BT_ALONE;
+		module->bt1_sw_type = BTC_SWITCH_V1_NONE;
+		break;
+	case 5:
+		module->ant.func[0] = BTC_EFMAP_NONE;
+		module->ant.func[1] = BTC_EFMAP_NONE;
+		module->ant.func[2] = BTC_EFMAP_BT0;
+		module->ant.func[3] = BTC_EFMAP_BT1;
+		module->ant.func[4] = BTC_EFMAP_ZB;
+		module->ant.type = BTC_ANT_DEDICATED;
+		module->bt0_pos = BTC_BT_ALONE;
+		module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+		module->bt1_pos = BTC_BT_ALONE;
+		module->bt1_sw_type = BTC_SWITCH_V1_NONE;
+		break;
 	}
-	rtwdev->btc.btg_pos = module->ant.btg_pos;
-	rtwdev->btc.ant_type = module->ant.type;
+
+	/*
+	 * if only BT0 at BTGA: 2-Ant, 3-Ant(BT1 used dedicated-ant)
+	 * can setup dm->wl_trx_nss_en = 1, WL MIMO-PS to 1T1R
+	 * (WL at WL-S0 only, BT0 at WL-S1)
+	 * tx_limit/rx_limit is decided by _set_trx_nss()
+	 */
+	if (dm->wl_trx_nss_en &&
+	    (dm->wl_trx_nss.tx_limit && dm->wl_trx_nss.rx_limit)) {
+		module->ant.type = BTC_ANT_DEDICATED;
+		module->ant.stream_cnt = 1;
+		dm->ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 0; /* wl 1ss-> RF-S0 */
+		dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 0; /* BT0-> RF-S1 */
+		dm->ant_xmap[BTC_RF_S0][BTC_BT_2ND] = 0;
+		dm->ant_xmap[BTC_RF_S1][BTC_BT_2ND] = 0; /* BT1 -> 3rd Ant */
+	}
+
+	/*
+	 * Todo: call HALBB API to set BT0/1 at WL_S0 or WL_S1
+	 * r_sel_gnt_bt_rx_path0[1:0], r_sel_gnt_bt_rx_path1[1:0]
+	 * WL_S0 with BT1 -> r_sel_gnt_bt_rx_path0[1:0]= 2b'10
+	 * WL_S1 with BT0 -> r_sel_gnt_bt_rx_path1[1:0]= 2b'01
+	 */
+
+	/* To Do: setup ext-SOC coex if exist */
+	switch (cx->bt_ext.chip_id) {
+	default:
+	case BTC_ESOC_NONE:
+		memset(&cx->bt_ext, 0, sizeof(struct rtw89_btc_extsoc_info));
+		cx->bt_ext.max_tx_pwr = RTW89_BTC_BT_DEF_LE_TX_PWR;
+		cx->bt_ext.ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO;
+		break;
+	case BTC_ESOC_8771:
+		cx->bt_ext.func_type = BTC_BTF_THREAD;
+		cx->bt_ext.hw_coex = BTC_EXTSOC_INTF_PTA;
+		cx->bt_ext.rf_band_map = 0x1; /* 2.4GHz only */
+		cx->bt_ext.link_weight[BTC_BT_B2G] = 10;
+		cx->bt_ext.profile_map[BTC_BT_B2G] |= BTC_BT_THREAD;
+		/* use GPIO 12~15 for Ext-4-wire-PTA */
+		cx->bt_ext.hpta_cfg = BIT(12) | BIT(13) | BIT(14) | BIT(15);
+		/* for Ext-SOC locate at Ant-2 */
+		if (module->ant.num >= 5)
+			module->ant.func[4] = BTC_EFMAP_ZB;
+		else
+			module->ant.func[module->ant.num - 1] = BTC_EFMAP_ZB;
+		break;
+	}
+
+	dm->ant_xmap[BTC_RF_S0][BTC_BT_EXT] = 0;
+	dm->ant_xmap[BTC_RF_S1][BTC_BT_EXT] = 0;
 }
 
 static void rtw8922d_btc_init_cfg(struct rtw89_dev *rtwdev)
-- 
2.25.1


  parent reply	other threads:[~2026-07-12  3:06 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-12  3:04 [PATCH rtw-next 00/11] wifi: rtw89: coex: implement coex for RTL8922D Ping-Ke Shih
2026-07-12  3:04 ` [PATCH rtw-next 01/11] wifi: rtw89: coex: Add Wi-Fi role info version 10 Ping-Ke Shih
2026-07-12  3:04 ` [PATCH rtw-next 02/11] wifi: rtw89: coex: Rearrange coexistence control structure Ping-Ke Shih
2026-07-12  3:04 ` [PATCH rtw-next 03/11] wifi: rtw89: coex: Update driver outsource info to firmware version 6 Ping-Ke Shih
2026-07-12  3:04 ` [PATCH rtw-next 04/11] wifi: rtw89: ceox: Update antenna & grant signal setting Ping-Ke Shih
2026-07-12  3:05 ` [PATCH rtw-next 05/11] wifi: rtw89: coex: Rearrange Bluetooth firmware report entry Ping-Ke Shih
2026-07-12  3:05 ` [PATCH rtw-next 06/11] wifi: rtw89: coex: Refine send firmware command function Ping-Ke Shih
2026-07-12  3:05 ` [PATCH rtw-next 07/11] wifi: rtw89: coex: Refine _reset_btc_var() Ping-Ke Shih
2026-07-12  3:05 ` Ping-Ke Shih [this message]
2026-07-12  3:05 ` [PATCH rtw-next 09/11] wifi: rtw89: coex: Add firmware report control report v11 Ping-Ke Shih
2026-07-12  3:05 ` [PATCH rtw-next 10/11] wifi: rtw89: coex: update external control length by case Ping-Ke Shih
2026-07-12  3:05 ` [PATCH rtw-next 11/11] wifi: rtw89: coex: Update coexistence version to 9.24.0 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=20260712030506.43438-9-pkshih@realtek.com \
    --to=pkshih@realtek.com \
    --cc=ku920601@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