Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings
@ 2026-11-12  6:05 Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 01/11] wifi: rtw89: coex: add a notify entry for dynamic MLO RF-path switch Ping-Ke Shih
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

Mainly update RTL8922D settings, including BT-coexistence, MLO control,
DAG and more register settings.

Patch 6-7 are to correct no 2GHz band condition, which a USB device
disables 2GHz band support, but some situations don't consider the
case properly, causing it throws warnings.

Ching-Te Ku (1):
  wifi: rtw89: coex: add a notify entry for dynamic MLO RF-path switch

Kuan-Chung Chen (3):
  wifi: rtw89: pci: reclaim TXBD before fully draining
  wifi: rtw89: 8922d: enable dynamic antenna gain
  wifi: rtw89: phy: fix antenna gain unit in debug output

Ping-Ke Shih (3):
  wifi: rtw89: 8922d: use efuse bias for CCK RX gain
  wifi: rtw89: 8922d: set CFR clip threshold while setting channel
  wifi: rtw89: 8922d: correct thermal trim range to -16~+16 programmed
    in efuse

Po-Hao Huang (1):
  wifi: rtw89: Update sequence for MLO link switch

Zong-Zhe Yang (3):
  wifi: rtw89: introduce bitmap of supported bands to deal with quirks
  wifi: rtw89: get default channel based on supported bands
  wifi: rtw89: fix band assignment in
    rtw89_core_update_rx_freq_from_ie()

 drivers/net/wireless/realtek/rtw89/chan.c     | 15 ++--
 drivers/net/wireless/realtek/rtw89/chan.h     |  2 +-
 drivers/net/wireless/realtek/rtw89/coex.c     | 62 +++++++++++++++
 drivers/net/wireless/realtek/rtw89/coex.h     | 11 +++
 drivers/net/wireless/realtek/rtw89/core.c     | 79 ++++++++++++++-----
 drivers/net/wireless/realtek/rtw89/core.h     | 17 +++-
 drivers/net/wireless/realtek/rtw89/debug.c    |  5 +-
 drivers/net/wireless/realtek/rtw89/fw.c       | 30 +++----
 drivers/net/wireless/realtek/rtw89/mac.c      |  5 +-
 drivers/net/wireless/realtek/rtw89/mac.h      | 24 ++++++
 drivers/net/wireless/realtek/rtw89/mac80211.c |  4 +-
 drivers/net/wireless/realtek/rtw89/mac_be.c   | 49 ++++++++++--
 drivers/net/wireless/realtek/rtw89/pci.c      |  4 +-
 drivers/net/wireless/realtek/rtw89/pci.h      |  1 +
 drivers/net/wireless/realtek/rtw89/phy.c      |  5 +-
 drivers/net/wireless/realtek/rtw89/ps.c       |  2 +-
 drivers/net/wireless/realtek/rtw89/reg.h      |  5 ++
 drivers/net/wireless/realtek/rtw89/regd.c     |  3 +-
 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 +
 drivers/net/wireless/realtek/rtw89/rtw8922d.c | 40 +++++++---
 drivers/net/wireless/realtek/rtw89/wow.c      |  5 +-
 25 files changed, 290 insertions(+), 83 deletions(-)


base-commit: 61a5eb87b2d9b4d5e353780b781cf691f39ba9e1
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 01/11] wifi: rtw89: coex: add a notify entry for dynamic MLO RF-path switch
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 02/11] wifi: rtw89: pci: reclaim TXBD before fully draining Ping-Ke Shih
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

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

MLO link combinations such as MLD2L1R_NONMLD let the firmware switch
the WL RF-path binding at runtime between 2+0, 0+2 and 1+1, instead of
keeping it fixed for the lifetime of the link. struct
rtw89_btc_wl_mlo_info already carries mrcx_mode, mrcx_act_hwb_map and
mrcx_bt_slot_rsp to describe that runtime state, and
rtw89_fw_h2c_cxdrv_mlo_v2() already forwards them to the firmware, but
nothing in the driver ever wrote these three fields. _set_bind_info()
and _set_coex_binding() both read mrcx_act_hwb_map to resolve which
HW-band a given WL RF-path currently serves while in this mode, and
with the field always zero they always resolved to the same band,
regardless of what the firmware actually switched to.

Add rtw89_btc_ntfy_mrcx_info(), a notify entry a caller can use to push
the current RF-path switch state into those three fields and let the
coex engine react to it. Mirroring the driver's existing per-HW-band
link_mode array, a mode change updates whichever MAC index the active
HW-band map selects, and a dual-band-MCC link mode is required before
any change is applied, since the RF-path binding is only ambiguous in
that state. A dedicated reason code and notify counter are added for
this entry so it can be told apart from other re-run triggers in coex
dumps.

This only adds the coex-internal entry point; nothing in the driver
calls it yet, since the trigger for a firmware-side RF-path switch
needs to be wired up from the MLO channel-context code.

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

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 61e8b601ca34..751ad0cfd4ea 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -978,6 +978,7 @@ enum btc_reason_and_action {
 	BTC_RSN_NTFY_SPECIFIC_PACKET,
 	BTC_RSN_NTFY_POWEROFF,
 	BTC_RSN_NTFY_ROLE_INFO,
+	BTC_RSN_NTFY_GENERIC,
 	BTC_RSN_CMD_SET_COEX,
 	BTC_RSN_ACT1_WORK,
 	BTC_RSN_BT_DEVINFO_WORK,
@@ -10529,6 +10530,67 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
 	}
 }
 
+void rtw89_btc_ntfy_mrcx_info(struct rtw89_dev *rtwdev,
+			      enum rtw89_mlo_coex_mode mode,
+			      u8 act_hwb_map, u8 bt_slot_rsp)
+{
+	struct rtw89_btc *btc = &rtwdev->btc;
+	struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+	struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
+	struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info;
+	bool link_mode_chg;
+	u8 link_mode;
+
+	rtw89_debug(rtwdev, RTW89_DBG_BTC,
+		    "[BTC], %s(): mode=%d, act_hwb_map=0x%x, bt_slot_rsp=%d\n",
+		    __func__, mode, act_hwb_map, bt_slot_rsp);
+	btc->dm.cnt_notify[BTC_NCNT_GENERIC]++;
+
+	mlo_info->mrcx_mode = mode;
+	mlo_info->mrcx_act_hwb_map = act_hwb_map;
+	mlo_info->mrcx_bt_slot_rsp = bt_slot_rsp;
+
+	if (wl_rinfo->link_mode[RTW89_MAC_0] != BTC_WLINK_DB_MCC &&
+	    wl_rinfo->link_mode[RTW89_MAC_1] != BTC_WLINK_DB_MCC)
+		return;
+
+	link_mode_chg = true;
+
+	/* the driver may change link mode to relieve band-switch effort */
+	switch (mode) {
+	case RTW89_MRCX_1CH_WB_H0:
+	case RTW89_MRCX_1CH_WB_H1:
+	case RTW89_MRCX_TDMRA_2CH_WB_WB:
+		link_mode = BTC_WLINK_STA;
+		break;
+	case RTW89_MRCX_TDMRA_1CH_W_B:
+		/*
+		 * both WL ports share one 2.4 GHz channel (W), BT
+		 * time-shares the remaining slots (B); treat as SCC.
+		 */
+		link_mode = BTC_WLINK_SCC;
+		break;
+	case RTW89_MRCX_TDMRA_2CH_W_W_B:
+		link_mode = BTC_WLINK_SB_MCC;
+		break;
+	default:
+		link_mode_chg = false;
+		break;
+	}
+
+	wl->link_mode_chg = link_mode_chg;
+
+	if (link_mode_chg) {
+		if (act_hwb_map & BIT(RTW89_MAC_0))
+			wl_rinfo->link_mode[RTW89_MAC_0] = link_mode;
+
+		if (act_hwb_map & BIT(RTW89_MAC_1))
+			wl_rinfo->link_mode[RTW89_MAC_1] = link_mode;
+	}
+
+	_run_coex(rtwdev, BTC_RSN_NTFY_GENERIC);
+}
+
 static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func)
 {
 	struct rtw89_btc *btc = &rtwdev->btc;
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index 38ffd0eff2c3..c3779cff9538 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -314,6 +314,14 @@ enum btc_mlo_rf_combin {
 	BTC_MLO_RF_2_PLUS_2 = 3,
 };
 
+enum rtw89_mlo_coex_mode {
+	RTW89_MRCX_1CH_WB_H0,
+	RTW89_MRCX_1CH_WB_H1,
+	RTW89_MRCX_TDMRA_1CH_W_B,
+	RTW89_MRCX_TDMRA_2CH_WB_WB,
+	RTW89_MRCX_TDMRA_2CH_W_W_B,
+};
+
 void rtw89_btc_init(struct rtw89_dev *rtwdev);
 void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev);
 void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev);
@@ -336,6 +344,9 @@ void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
 			   enum btc_wl_rfk_type type,
 			   enum btc_wl_rfk_state state);
 void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev);
+void rtw89_btc_ntfy_mrcx_info(struct rtw89_dev *rtwdev,
+			      enum rtw89_mlo_coex_mode mode,
+			      u8 act_hwb_map, u8 bt_slot_rsp);
 void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 			  u32 len, u8 class, u8 func);
 ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz);
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7f84ee59f825..01da0b30a7ab 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1364,6 +1364,7 @@ enum rtw89_btc_ncnt {
 	BTC_NCNT_RFK_TIMEOUT,
 	BTC_NCNT_SHOW_COEX_INFO,
 	BTC_NCNT_ROLE_INFO,
+	BTC_NCNT_GENERIC,
 	BTC_NCNT_CONTROL,
 	BTC_NCNT_RADIO_STATE,
 	BTC_NCNT_CUSTOMERIZE,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 02/11] wifi: rtw89: pci: reclaim TXBD before fully draining
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 01/11] wifi: rtw89: coex: add a notify entry for dynamic MLO RF-path switch Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 03/11] wifi: rtw89: 8922d: use efuse bias for CCK RX gain Ping-Ke Shih
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Kuan-Chung Chen <damon.chen@realtek.com>

Currently, we reclaim TXBD only when the available resource is 0.
When two ACs share the same DMA channel, the lower-priority AC
occupies the whole channel, which affects the higher-priority
AC's throughput.

Add RTW89_PCI_TXBD_RECLAIM_TH to reclaim early once the
available resource falls below it, improving TX
fairness between ACs sharing a DMA channel.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/pci.c | 4 ++--
 drivers/net/wireless/realtek/rtw89/pci.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 6d19e759fc0d..76523d057825 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -1281,7 +1281,7 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
 	bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
 	wd_cnt = wd_ring->curr_num;
 
-	if (wd_cnt == 0 || bd_cnt == 0) {
+	if (wd_cnt == 0 || bd_cnt < RTW89_PCI_TXBD_RECLAIM_TH) {
 		cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring);
 		if (cnt)
 			rtw89_pci_release_tx(rtwdev, rx_ring, cnt);
@@ -1289,7 +1289,7 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
 			goto out_unlock;
 
 		bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
-		if (bd_cnt == 0)
+		if (bd_cnt < RTW89_PCI_TXBD_RECLAIM_TH)
 			rtw89_pci_reclaim_txbd(rtwdev, tx_ring);
 	}
 
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
index 0f9ea4bf54ea..3cc484bc1ca8 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.h
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
@@ -1120,6 +1120,7 @@
 #define B_BE_MAX_TAG_NUM_MASK GENMASK(3, 0)
 
 #define RTW89_PCI_TXBD_NUM_MAX		256
+#define RTW89_PCI_TXBD_RECLAIM_TH	(RTW89_PCI_TXBD_NUM_MAX >> 1)
 #define RTW89_PCI_RXBD_NUM_MAX		256
 #define RTW89_PCI_TXWD_NUM_MAX		512
 #define RTW89_PCI_TXWD_PAGE_SIZE	128
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 03/11] wifi: rtw89: 8922d: use efuse bias for CCK RX gain
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 01/11] wifi: rtw89: coex: add a notify entry for dynamic MLO RF-path switch Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 02/11] wifi: rtw89: pci: reclaim TXBD before fully draining Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 04/11] wifi: rtw89: 8922d: set CFR clip threshold while setting channel Ping-Ke Shih
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

Instead of deriving the CCK RX gain compensation from BW20/BW40 gain bias
and CCK RPL offset fields, write the calibration efuse gain value directly
to the efuse bias field.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.h     | 1 +
 drivers/net/wireless/realtek/rtw89/reg.h      | 1 +
 drivers/net/wireless/realtek/rtw89/rtw8922d.c | 9 +++------
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 01da0b30a7ab..afec4e166b78 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -7437,6 +7437,7 @@ struct rtw89_phy_calc_efuse_gain {
 	s8 cck_mean_gain_bias;
 	s8 cck_rpl_ofst;
 	s8 rssi_ofst;
+	s8 cck_efuse_bias;
 };
 
 #define RTW89_MAX_PATTERN_NUM             18
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 4829f9fd8eb5..edbfc9514a08 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -11003,6 +11003,7 @@
 #define R_CCK_FC0_INV_BE4 0x26090
 #define B_CCK_FC0_INV_BE4 GENMASK(18, 0)
 #define R_GAIN_BIAS_BE4 0x260A0
+#define B_EFUSE_BIAS_BE4 GENMASK(5, 0)
 #define B_GAIN_BIAS_BW20_BE4 GENMASK(11, 6)
 #define B_GAIN_BIAS_BW40_BE4 GENMASK(17, 12)
 
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 43d9df619260..b874bac9bfee 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -1720,6 +1720,7 @@ static void rtw8922d_calc_rx_gain_normal_cck(struct rtw89_dev *rtwdev,
 	rx_gain_offset = -rtw8922d_get_rx_gain_by_chan(rtwdev, chan, path, true);
 	calc->cck_mean_gain_bias = (rx_gain_offset & 0x3) << 1;
 	calc->cck_rpl_ofst = (rx_gain_offset >> 2) + gain->cck_rpl_base[phy_idx];
+	calc->cck_efuse_bias = rx_gain_offset;
 }
 
 static void rtw8922d_set_rx_gain_normal_cck(struct rtw89_dev *rtwdev,
@@ -1731,12 +1732,8 @@ static void rtw8922d_set_rx_gain_normal_cck(struct rtw89_dev *rtwdev,
 
 	rtw8922d_calc_rx_gain_normal_cck(rtwdev, chan, path, phy_idx, &calc);
 
-	rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_GAIN_BIAS_BW20_BE4,
-			      calc.cck_mean_gain_bias, phy_idx);
-	rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_GAIN_BIAS_BW40_BE4,
-			      calc.cck_mean_gain_bias, phy_idx);
-	rtw89_phy_write32_idx(rtwdev, R_CCK_RPL_OFST_BE4, B_CCK_RPL_OFST_BE4,
-			      calc.cck_rpl_ofst, phy_idx);
+	rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_EFUSE_BIAS_BE4,
+			      calc.cck_efuse_bias, phy_idx);
 }
 
 static void rtw8922d_calc_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 04/11] wifi: rtw89: 8922d: set CFR clip threshold while setting channel
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (2 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 03/11] wifi: rtw89: 8922d: use efuse bias for CCK RX gain Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 05/11] wifi: rtw89: 8922d: correct thermal trim range to -16~+16 programmed in efuse Ping-Ke Shih
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

Set thresholds to let CFR circuit to clip TX peak amplitudes per band.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/reg.h      |  3 +++
 drivers/net/wireless/realtek/rtw89/rtw8922d.c | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index edbfc9514a08..4bee9f66038c 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -10967,6 +10967,9 @@
 #define R_OFDM_RPL_BIAS_P1_BE4 0x2460C
 #define B_OFDM_RPL_BIAS_P1_BE4 GENMASK(11, 2)
 #define R_TX_CFR_MANUAL_EN_BE4 0x2483C
+#define B_TX_CFR_CLIP_TH0_BE4 GENMASK(19, 15)
+#define B_TX_CFR_CLIP_TH1_BE4 GENMASK(24, 20)
+#define B_TX_CFR_CLIP_TH2_BE4 GENMASK(29, 25)
 #define B_TX_CFR_MANUAL_EN_BE4_M BIT(30)
 #define R_PCOEFF0_BE4 0x24880
 #define B_PCOEFF01_BE4 GENMASK(23, 0)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index b874bac9bfee..ca7491bb9045 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -1969,6 +1969,23 @@ static void rtw8922d_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_sb, u8 bw,
 	}
 }
 
+static void rtw8922d_cfr_clip_th(struct rtw89_dev *rtwdev,
+				 const struct rtw89_chan *chan,
+				 enum rtw89_phy_idx phy_idx)
+{
+	static const u32 clip_th0[RTW89_BAND_NUM] = {0x8, 0x8, 0x8};
+	static const u32 clip_th1[RTW89_BAND_NUM] = {0x18, 0x14, 0x14};
+	static const u32 clip_th2[RTW89_BAND_NUM] = {0x8, 0x8, 0x8};
+	u8 band = chan->band_type;
+
+	rtw89_phy_write32_idx(rtwdev, R_TX_CFR_MANUAL_EN_BE4, B_TX_CFR_CLIP_TH0_BE4,
+			      clip_th0[band], phy_idx);
+	rtw89_phy_write32_idx(rtwdev, R_TX_CFR_MANUAL_EN_BE4, B_TX_CFR_CLIP_TH1_BE4,
+			      clip_th1[band], phy_idx);
+	rtw89_phy_write32_idx(rtwdev, R_TX_CFR_MANUAL_EN_BE4, B_TX_CFR_CLIP_TH2_BE4,
+			      clip_th2[band], phy_idx);
+}
+
 static const u16 spur_nbi_a[] = {6400};
 static const u16 spur_csi[] = {6400};
 
@@ -2551,6 +2568,7 @@ static void rtw8922d_set_channel_bb(struct rtw89_dev *rtwdev,
 
 	rtw8922d_ctrl_ch(rtwdev, chan, phy_idx);
 	rtw8922d_ctrl_bw(rtwdev, pri_sb, chan->band_width, phy_idx);
+	rtw8922d_cfr_clip_th(rtwdev, chan, phy_idx);
 	rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(rtwdev, chan, phy_idx);
 
 	if (cck_en)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 05/11] wifi: rtw89: 8922d: correct thermal trim range to -16~+16 programmed in efuse
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (3 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 04/11] wifi: rtw89: 8922d: set CFR clip threshold while setting channel Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 06/11] wifi: rtw89: introduce bitmap of supported bands to deal with quirks Ping-Ke Shih
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

The thermal trim value in efuse can be -16 and +16 for productions.
Correct the range accordingly. Otherwise, wrong trim value 0 is adopted.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/rtw8922d.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index ca7491bb9045..2bc46be72e0a 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -1015,8 +1015,8 @@ static void rtw8922d_vco_trim(struct rtw89_dev *rtwdev)
 
 #define THM_TRIM_POSITIVE_MASK BIT(6)
 #define THM_TRIM_MAGNITUDE_MASK GENMASK(5, 0)
-#define THM_TRIM_MAX (15)
-#define THM_TRIM_MIN (-15)
+#define THM_TRIM_MAX (16)
+#define THM_TRIM_MIN (-16)
 
 static void rtw8922d_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
 						 u8 *phycap_map)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 06/11] wifi: rtw89: introduce bitmap of supported bands to deal with quirks
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (4 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 05/11] wifi: rtw89: 8922d: correct thermal trim range to -16~+16 programmed in efuse Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 07/11] wifi: rtw89: get default channel based on supported bands Ping-Ke Shih
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Zong-Zhe Yang <kevin_yang@realtek.com>

The RTW89_QUIRK_DISABLE_2GHZ only blocked registering NL80211_BAND_2GHZ
in wiphy->bands, but didn't handle other SW logic. Other SW flow still
determined things based on chip->support_bands, and caused inconsistent
behavior.

Introduce supported_bands bitmap which is set by intersection of quirks
and chip->support_bands when initializing core. Besides, initialize quirks
when allocating HW.

Fixes: 355626a2c232 ("wifi: rtw89: 8852cu: add quirk to disable 2.4 GHz band")
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c  | 37 ++++++++++++++--------
 drivers/net/wireless/realtek/rtw89/core.h  |  1 +
 drivers/net/wireless/realtek/rtw89/debug.c |  5 +--
 drivers/net/wireless/realtek/rtw89/fw.c    | 30 ++++++------------
 drivers/net/wireless/realtek/rtw89/mac.c   |  3 +-
 drivers/net/wireless/realtek/rtw89/regd.c  |  3 +-
 drivers/net/wireless/realtek/rtw89/wow.c   |  5 +--
 7 files changed, 37 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index b7df97e7d622..4467ca25f1b0 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2584,7 +2584,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
 	if (rx_status->band != NL80211_BAND_6GHZ)
 		return;
 
-	if (unlikely(!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))) {
+	if (unlikely(!test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands))) {
 		rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "invalid rx on unsupported 6 GHz\n");
 		return;
 	}
@@ -6427,13 +6427,9 @@ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
 {
 	struct ieee80211_hw *hw = rtwdev->hw;
 	struct ieee80211_supported_band *sband;
-	u8 support_bands = rtwdev->chip->support_bands;
 	int ret;
 
-	if (test_bit(RTW89_QUIRK_DISABLE_2GHZ, rtwdev->quirks))
-		support_bands &= ~BIT(NL80211_BAND_2GHZ);
-
-	if (support_bands & BIT(NL80211_BAND_2GHZ)) {
+	if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands)) {
 		sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_2ghz);
 		if (!sband)
 			return -ENOMEM;
@@ -6444,7 +6440,7 @@ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
 		hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;
 	}
 
-	if (support_bands & BIT(NL80211_BAND_5GHZ)) {
+	if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands)) {
 		sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_5ghz);
 		if (!sband)
 			return -ENOMEM;
@@ -6456,7 +6452,7 @@ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
 		hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;
 	}
 
-	if (support_bands & BIT(NL80211_BAND_6GHZ)) {
+	if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands)) {
 		sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_6ghz);
 		if (!sband)
 			return -ENOMEM;
@@ -6970,6 +6966,22 @@ void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id)
 	list_del(&link->dlink_schd);
 }
 
+static void rtw89_core_init_supported_bands(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+	enum nl80211_band band;
+
+	for (band = 0; band < NUM_NL80211_BANDS; band++) {
+		if (!(chip->support_bands & BIT(band)))
+			continue;
+
+		set_bit(band, rtwdev->supported_bands);
+	}
+
+	if (test_bit(RTW89_QUIRK_DISABLE_2GHZ, rtwdev->quirks))
+		clear_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands);
+}
+
 int rtw89_core_init(struct rtw89_dev *rtwdev)
 {
 	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -6978,18 +6990,14 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
 
 	rtwdev->io = rtw89_fw_cmd_ofld_alloc_and_get_io_ops(rtwdev);
 
-	bitmap_or(rtwdev->quirks, rtwdev->quirks, &rtwdev->chip->default_quirks,
-		  NUM_OF_RTW89_QUIRKS);
+	rtw89_core_init_supported_bands(rtwdev);
 
 	INIT_LIST_HEAD(&rtwdev->ba_list);
 	INIT_LIST_HEAD(&rtwdev->forbid_ba_list);
 	INIT_LIST_HEAD(&rtwdev->rtwvifs_list);
 	INIT_LIST_HEAD(&rtwdev->early_h2c_list);
-	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
-		if (!(rtwdev->chip->support_bands & BIT(band)))
-			continue;
+	for_each_set_bit(band, rtwdev->supported_bands, NUM_NL80211_BANDS)
 		INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]);
-	}
 	INIT_LIST_HEAD(&rtwdev->scan_info.chan_list);
 	INIT_LIST_HEAD(&rtwdev->tx_waits);
 	INIT_LIST_HEAD(&rtwdev->fw.dup_data_list);
@@ -7722,6 +7730,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
 	rtwdev->fw.fw_format = fw_format;
 	rtwdev->support_mlo = support_mlo;
 
+	bitmap_copy(rtwdev->quirks, &chip->default_quirks, NUM_OF_RTW89_QUIRKS);
 	bitmap_or(rtwdev->quirks, rtwdev->quirks, dev_id_quirks,
 		  NUM_OF_RTW89_QUIRKS);
 
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index afec4e166b78..2a691daf7dab 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -7753,6 +7753,7 @@ struct rtw89_dev {
 
 	struct rtw89_ser ser;
 
+	DECLARE_BITMAP(supported_bands, NUM_NL80211_BANDS);
 	DECLARE_BITMAP(hw_port, RTW89_PORT_NUM);
 	DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM);
 	DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS);
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 3ebe4aa04e2b..9d680360a89b 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -4747,12 +4747,9 @@ static ssize_t rtw89_debug_priv_stations_get(struct rtw89_dev *rtwdev,
 		       (int)sizeof(rtwdev->pkt_offload),
 		       rtwdev->pkt_offload);
 
-	for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
-		if (!(rtwdev->chip->support_bands & BIT(idx)))
-			continue;
+	for_each_set_bit(idx, rtwdev->supported_bands, NUM_NL80211_BANDS)
 		p += rtw89_dump_pkt_offload(p, end - p, &rtwdev->scan_info.pkt_list[idx],
 					    "\t\t[SCAN %u]: ", idx);
-	}
 
 	rtw89_debugfs_iter_data_setup(&iter_data, p, end - p);
 	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index e965aca66fdc..72882fe14d77 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -1328,7 +1328,6 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
 				       const union rtw89_fw_element_arg arg)
 {
 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
-	const struct rtw89_chip_info *chip = rtwdev->chip;
 	const struct rtw89_fw_element_hdr *elm_dup;
 	struct rtw89_hal *hal = &rtwdev->hal;
 	u16 aid = le16_to_cpu(elm->aid);
@@ -1341,11 +1340,11 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
 	if (aid && aid != hal->aid)
 		return 1;
 
-	if (chip->support_bands & BIT(NL80211_BAND_6GHZ))
+	if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands))
 		needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ;
-	if (chip->support_bands & BIT(NL80211_BAND_5GHZ))
+	if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands))
 		needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ;
-	if (chip->support_bands & BIT(NL80211_BAND_2GHZ))
+	if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands))
 		needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ;
 
 	bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
@@ -9920,10 +9919,7 @@ static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev)
 	struct rtw89_pktofld_info *info, *tmp;
 	u8 idx, wildcard_pkt_id;
 
-	for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
-		if (!(rtwdev->chip->support_bands & BIT(idx)))
-			continue;
-
+	for_each_set_bit(idx, rtwdev->supported_bands, NUM_NL80211_BANDS) {
 		wildcard_pkt_id = scan_info->wildcard_pkt_id[idx];
 		if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE)
 			rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id);
@@ -9987,10 +9983,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
 	int ret = 0;
 	u8 band;
 
-	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
-		if (!(rtwdev->chip->support_bands & BIT(band)))
-			continue;
-
+	for_each_set_bit(band, rtwdev->supported_bands, NUM_NL80211_BANDS) {
 		new = skb_copy(skb, GFP_KERNEL);
 		if (!new) {
 			ret = -ENOMEM;
@@ -10039,10 +10032,7 @@ int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev,
 	int ret;
 	u8 id;
 
-	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
-		if (!(rtwdev->chip->support_bands & BIT(band)))
-			continue;
-
+	for_each_set_bit(band, rtwdev->supported_bands, NUM_NL80211_BANDS) {
 		if (wowlan) {
 			nd_config = rtw_wow->nd_config;
 
@@ -13090,17 +13080,15 @@ void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data)
 static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev,
 					const struct rtw89_rfe_parms *parms)
 {
-	const struct rtw89_chip_info *chip = rtwdev->chip;
-
-	if (chip->support_bands & BIT(NL80211_BAND_2GHZ) &&
+	if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands) &&
 	    !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru))
 		return false;
 
-	if (chip->support_bands & BIT(NL80211_BAND_5GHZ) &&
+	if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands) &&
 	    !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru))
 		return false;
 
-	if (chip->support_bands & BIT(NL80211_BAND_6GHZ) &&
+	if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands) &&
 	    !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru))
 		return false;
 
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 41796bff08ed..11b6c6510050 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -5319,8 +5319,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 	actual_period = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PERIOD);
 	mac_idx = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_MAC_IDX);
 
-
-	if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))
+	if (!test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands))
 		band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
 
 	if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c
index f75ce808254c..017e6a2b4b0d 100644
--- a/drivers/net/wireless/realtek/rtw89/regd.c
+++ b/drivers/net/wireless/realtek/rtw89/regd.c
@@ -587,8 +587,7 @@ static void rtw89_regd_setup_policy_6ghz_vlp(struct rtw89_dev *rtwdev)
 
 static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
 {
-	const struct rtw89_chip_info *chip = rtwdev->chip;
-	bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ);
+	bool chip_support_6ghz = test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands);
 	bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB;
 	bool regd_allow_6ghz = chip_support_6ghz;
 	struct ieee80211_supported_band *sband;
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index 928faf71c239..91fbb6d28069 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -1470,10 +1470,7 @@ static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
 	struct rtw89_pktofld_info *info, *tmp;
 	u8 idx, wildcard_pkt_id;
 
-	for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
-		if (!(rtwdev->chip->support_bands & BIT(idx)))
-			continue;
-
+	for_each_set_bit(idx, rtwdev->supported_bands, NUM_NL80211_BANDS) {
 		wildcard_pkt_id = scan_info->wildcard_pkt_id[idx];
 		if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE)
 			rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 07/11] wifi: rtw89: get default channel based on supported bands
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (5 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 06/11] wifi: rtw89: introduce bitmap of supported bands to deal with quirks Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 08/11] wifi: rtw89: fix band assignment in rtw89_core_update_rx_freq_from_ie() Ping-Ke Shih
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Zong-Zhe Yang <kevin_yang@realtek.com>

Previously, because all chipsets support 2 GHz, default channel was
always one of 2 GHz. However, after adding RTW89_QUIRK_DISABLE_2GHZ,
wiphy might not really register NL80211_BAND_2GHZ.

Refine logic to get default channel based on bitmap of supported bands.
Besides, throw an error if there is no any supported bands to use.

Fixes: 355626a2c232 ("wifi: rtw89: 8852cu: add quirk to disable 2.4 GHz band")
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c | 15 +++++++----
 drivers/net/wireless/realtek/rtw89/chan.h |  2 +-
 drivers/net/wireless/realtek/rtw89/core.c | 32 ++++++++++++++++++++---
 drivers/net/wireless/realtek/rtw89/core.h |  2 +-
 4 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index a7ba47bd9abd..6a4ea1c3f9ca 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -293,15 +293,20 @@ void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
 	}
 }
 
-static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
+static int rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
 {
-	struct cfg80211_chan_def chandef = {0};
+	struct cfg80211_chan_def chandef = {};
+	int ret;
+
+	ret = rtw89_get_default_chandef(rtwdev, &chandef);
+	if (ret)
+		return ret;
 
-	rtw89_get_default_chandef(&chandef);
 	__rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef);
+	return 0;
 }
 
-void rtw89_entity_init(struct rtw89_dev *rtwdev)
+int rtw89_entity_init(struct rtw89_dev *rtwdev)
 {
 	struct rtw89_hal *hal = &rtwdev->hal;
 	struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
@@ -321,7 +326,7 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
 
 	hal->entity_force_hw = RTW89_PHY_NUM;
 
-	rtw89_config_default_chandef(rtwdev);
+	return rtw89_config_default_chandef(rtwdev);
 }
 
 static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif)
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index e9df90c4ce3c..509e64dfcd6d 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -172,7 +172,7 @@ void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
 void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
 			      struct rtw89_vif_link *rtwvif_link,
 			      const struct cfg80211_chan_def *chandef);
-void rtw89_entity_init(struct rtw89_dev *rtwdev);
+int rtw89_entity_init(struct rtw89_dev *rtwdev);
 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
 bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 4467ca25f1b0..1ef8cf5f2dfd 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -401,10 +401,30 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
 	}
 }
 
-void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef)
+static struct ieee80211_channel *rtw89_core_get_default_channel(struct rtw89_dev *rtwdev)
 {
-	cfg80211_chandef_create(chandef, &rtw89_channels_2ghz[0],
-				NL80211_CHAN_NO_HT);
+	if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands))
+		return &rtw89_channels_2ghz[0];
+	if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands))
+		return &rtw89_channels_5ghz[0];
+	if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands))
+		return &rtw89_channels_6ghz[0];
+
+	return NULL;
+}
+
+int rtw89_get_default_chandef(struct rtw89_dev *rtwdev, struct cfg80211_chan_def *chandef)
+{
+	struct ieee80211_channel *dflt;
+
+	dflt = rtw89_core_get_default_channel(rtwdev);
+	if (unlikely(!dflt)) {
+		rtw89_err(rtwdev, "no valid default channel\n");
+		return -EINVAL;
+	}
+
+	cfg80211_chandef_create(chandef, dflt, NL80211_CHAN_NO_HT);
+	return 0;
 }
 
 void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
@@ -6987,6 +7007,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
 	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
 	struct rtw89_btc *btc = &rtwdev->btc;
 	u8 band;
+	int ret;
 
 	rtwdev->io = rtw89_fw_cmd_ofld_alloc_and_get_io_ops(rtwdev);
 
@@ -7062,8 +7083,11 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
 
 	schedule_work(&rtwdev->load_firmware_work);
 
+	ret = rtw89_entity_init(rtwdev);
+	if (ret)
+		return ret;
+
 	rtw89_ser_init(rtwdev);
-	rtw89_entity_init(rtwdev);
 	rtw89_sar_init(rtwdev);
 	rtw89_phy_ant_gain_init(rtwdev);
 
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 2a691daf7dab..48ef07b1d48f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -9534,7 +9534,7 @@ void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
 			    struct rtw89_vif_link *rtwvif_link);
 const struct rtw89_6ghz_span *
 rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq);
-void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
+int rtw89_get_default_chandef(struct rtw89_dev *rtwdev, struct cfg80211_chan_def *chandef);
 void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
 			      struct rtw89_chan *chan);
 int rtw89_set_channel(struct rtw89_dev *rtwdev);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 08/11] wifi: rtw89: fix band assignment in rtw89_core_update_rx_freq_from_ie()
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (6 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 07/11] wifi: rtw89: get default channel based on supported bands Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 09/11] wifi: rtw89: Update sequence for MLO link switch Ping-Ke Shih
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Zong-Zhe Yang <kevin_yang@realtek.com>

The rx_status->band expects enum nl80211_band instead of enum rtw89_band.
Convert band from enum rtw89_band to enum nl80211_band before assignment.

Fortunately, this problematic code had previously produced valid values,
but fixing it should be better.

Fixes: e16acf907a3c ("wifi: rtw89: Parse channel from IE to correct invalid hardware reports during scanning")
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 1ef8cf5f2dfd..67e84bcdc631 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -3835,6 +3835,7 @@ static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev,
 {
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
 	size_t hdr_len, ielen;
+	enum rtw89_band tmp;
 	u8 *variable;
 	int chan;
 
@@ -3868,7 +3869,8 @@ static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev,
 	if (chan == -1)
 		return;
 
-	rx_status->band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
+	tmp = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
+	rx_status->band = rtw89_hw_to_nl80211_band(tmp);
 	rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band);
 }
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 09/11] wifi: rtw89: Update sequence for MLO link switch
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (7 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 08/11] wifi: rtw89: fix band assignment in rtw89_core_update_rx_freq_from_ie() Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:05 ` [PATCH rtw-next 10/11] wifi: rtw89: 8922d: enable dynamic antenna gain Ping-Ke Shih
  2026-11-12  6:06 ` [PATCH rtw-next 11/11] wifi: rtw89: phy: fix antenna gain unit in debug output Ping-Ke Shih
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Po-Hao Huang <phhuang@realtek.com>

Add missing flow when switching MLO links. Fix unexpected RTL8922D
FW behavior. In MLSR mode, when only single link information is
initialized, enabling hardware to switch link arbitrarily causes FW
errors. This register will be set only in the future patches where
change link is a must, e.g. eMLSR.

Recalculate the current active band and do corresponding TX
settings before authentication and returning from power save mode,
to keep hardware from sending packets from inactive bands.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c     |  6 +++
 drivers/net/wireless/realtek/rtw89/core.h     | 12 +++++
 drivers/net/wireless/realtek/rtw89/mac.c      |  2 +
 drivers/net/wireless/realtek/rtw89/mac.h      | 24 +++++++++
 drivers/net/wireless/realtek/rtw89/mac80211.c |  4 +-
 drivers/net/wireless/realtek/rtw89/mac_be.c   | 49 ++++++++++++++++---
 drivers/net/wireless/realtek/rtw89/ps.c       |  2 +-
 drivers/net/wireless/realtek/rtw89/reg.h      |  1 +
 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 +
 drivers/net/wireless/realtek/rtw89/rtw8922d.c |  7 +++
 14 files changed, 101 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 67e84bcdc631..b26964f09679 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -5488,6 +5488,12 @@ static void rtw89_core_mlo_track(struct rtw89_dev *rtwdev)
 	}
 }
 
+void rtw89_core_config_active_bands(struct rtw89_dev *rtwdev)
+{
+	rtw89_fw_h2c_init_trx_protect(rtwdev);
+	rtw89_mac_init_drv_txen(rtwdev);
+}
+
 static void rtw89_track_ps_work(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 48ef07b1d48f..b7f889d55f60 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4991,6 +4991,7 @@ struct rtw89_chip_ops {
 	void (*fem_setup)(struct rtw89_dev *rtwdev);
 	int (*data_setup)(struct rtw89_dev *rtwdev);
 	void (*rfe_gpio)(struct rtw89_dev *rtwdev);
+	void (*cfg_hw_mlo)(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);
@@ -8871,6 +8872,14 @@ static inline void rtw89_chip_rfe_gpio(struct rtw89_dev *rtwdev)
 		chip->ops->rfe_gpio(rtwdev);
 }
 
+static inline void rtw89_chip_cfg_hw_mlo(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+
+	if (chip->ops->cfg_hw_mlo)
+		chip->ops->cfg_hw_mlo(rtwdev);
+}
+
 static inline void rtw89_chip_rfk_hw_init(struct rtw89_dev *rtwdev)
 {
 	const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -9443,6 +9452,7 @@ static inline u32 rtw89_bytes_to_mbps(u64 bytes, enum rtw89_tfc_interval interva
 
 int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
 			struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel);
+void rtw89_core_init_drv_txen(struct rtw89_dev *rtwdev);
 int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
 		 struct sk_buff *skb, bool fwdl);
 void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel);
@@ -9532,6 +9542,7 @@ void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id);
 void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
 void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
 			    struct rtw89_vif_link *rtwvif_link);
+void rtw89_chip_hw_mlo_config(struct rtw89_dev *rtwdev);
 const struct rtw89_6ghz_span *
 rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq);
 int rtw89_get_default_chandef(struct rtw89_dev *rtwdev, struct cfg80211_chan_def *chandef);
@@ -9599,6 +9610,7 @@ void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev,
 			       enum rtw89_phy_idx phy_idx);
 int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 			   unsigned int link_id);
+void rtw89_core_config_active_bands(struct rtw89_dev *rtwdev);
 void rtw89_core_dm_disable_cfg(struct rtw89_dev *rtwdev, u32 new);
 void rtw89_core_dm_disable_set(struct rtw89_dev *rtwdev, enum rtw89_dm_type type);
 void rtw89_core_dm_disable_clr(struct rtw89_dev *rtwdev, enum rtw89_dm_type type);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 11b6c6510050..598ce5e93ad7 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -7568,6 +7568,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
 	.dle_func_en = dle_func_en_ax,
 	.dle_clk_en = dle_clk_en_ax,
 	.bf_assoc = rtw89_mac_bf_assoc_ax,
+	.mlo_link_cfg = NULL,
+	.init_drv_txen = NULL,
 
 	.typ_fltr_opt = rtw89_mac_typ_fltr_opt_ax,
 	.cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_ax,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index db42e33e694c..2e76bb1d1519 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -1095,6 +1095,10 @@ struct rtw89_mac_gen_def {
 	void (*bf_assoc)(struct rtw89_dev *rtwdev,
 			 struct rtw89_vif_link *rtwvif_link,
 			 struct rtw89_sta_link *rtwsta_link);
+	void (*mlo_link_cfg)(struct rtw89_dev *rtwdev,
+			     struct rtw89_vif_link *rtwvif_link,
+			     bool enable);
+	void (*init_drv_txen)(struct rtw89_dev *rtwdev);
 
 	int (*typ_fltr_opt)(struct rtw89_dev *rtwdev,
 			    enum rtw89_machdr_frame_type type,
@@ -1545,6 +1549,26 @@ void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev,
 		mac->bf_assoc(rtwdev, rtwvif_link, rtwsta_link);
 }
 
+static inline
+void rtw89_mac_mlo_link_cfg(struct rtw89_dev *rtwdev,
+			    struct rtw89_vif_link *rtwvif_link,
+			    bool enable)
+{
+	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+	if (mac->mlo_link_cfg)
+		mac->mlo_link_cfg(rtwdev, rtwvif_link, enable);
+}
+
+static inline
+void rtw89_mac_init_drv_txen(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+	if (mac->init_drv_txen)
+		mac->init_drv_txen(rtwdev);
+}
+
 void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
 			   struct rtw89_vif_link *rtwvif_link,
 			   struct rtw89_sta_link *rtwsta_link);
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 9134cdce2f47..c85ea82860c0 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -548,7 +548,7 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev,
 	if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
 		rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
 
-	rtw89_fw_h2c_init_trx_protect(rtwdev);
+	rtw89_core_config_active_bands(rtwdev);
 
 	return 0;
 
@@ -1716,7 +1716,7 @@ static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev,
 		if (unlikely(!rtwvif_link))
 			continue;
 
-		rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, en);
+		rtw89_mac_mlo_link_cfg(rtwdev, rtwvif_link, en);
 	}
 }
 
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index fa35cafd7074..2b874825f503 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -1093,9 +1093,7 @@ static int txpktctrl_init_be(struct rtw89_dev *rtwdev)
 
 static int mlo_init_be(struct rtw89_dev *rtwdev)
 {
-	const struct rtw89_chip_info *chip = rtwdev->chip;
 	u32 val32;
-	u32 reg;
 	int ret;
 
 	rtw89_io_pack(rtwdev);
@@ -1114,14 +1112,8 @@ static int mlo_init_be(struct rtw89_dev *rtwdev)
 	if (ret)
 		rtw89_err(rtwdev, "[MLO]%s: MLO init polling timeout\n", __func__);
 
-	if (chip->chip_id == RTL8922A)
-		reg = R_BE_SS_CTRL;
-	else
-		reg = R_BE_SS_CTRL_V1;
-
 	rtw89_io_pack(rtwdev);
 
-	rtw89_write32_set(rtwdev, reg, B_BE_MLO_HW_CHGLINK_EN);
 	rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_ACQCHK_CFG_0, B_BE_R_MACID_ACQ_CHK_EN);
 
 	rtw89_io_unpack(rtwdev);
@@ -2949,6 +2941,45 @@ static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
 	}
 }
 
+static void rtw89_mac_mlo_link_cfg_be(struct rtw89_dev *rtwdev,
+				      struct rtw89_vif_link *rtwvif_link,
+				      bool enable)
+{
+	u32 reg, tx_en;
+
+	if (enable) {
+		rtw89_chip_cfg_hw_mlo(rtwdev);
+		rtw89_chip_resume_sch_tx(rtwdev, rtwvif_link->phy_idx,
+					 B_BE_CTN_TXEN_ALL_MASK);
+		rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, enable);
+	} else {
+		rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, enable);
+		rtw89_chip_stop_sch_tx(rtwdev, rtwvif_link->phy_idx, &tx_en,
+				       RTW89_SCH_TX_SEL_ALL);
+	}
+
+	if (rtwdev->chip->chip_id == RTL8922A)
+		reg = R_BE_SS_CTRL;
+	else
+		reg = R_BE_SS_CTRL_V1;
+
+	rtw89_write32_clr(rtwdev, reg, B_BE_MLO_HW_CHGLINK_EN);
+}
+
+static void rtw89_mac_init_drv_txen_be(struct rtw89_dev *rtwdev)
+{
+	u8 active_bands = rtw89_get_active_phy_bitmap(rtwdev);
+	u32 tx_en;
+	int i;
+
+	for (i = 0; i < RTW89_PHY_NUM; i++) {
+		if (active_bands & BIT(i))
+			rtw89_chip_resume_sch_tx(rtwdev, i, B_BE_CTN_TXEN_ALL_MASK);
+		else
+			rtw89_chip_stop_sch_tx(rtwdev, i, &tx_en, RTW89_SCH_TX_SEL_ALL);
+	}
+}
+
 static void dump_err_status_dispatcher_be(struct rtw89_dev *rtwdev)
 {
 	rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x ",
@@ -3313,6 +3344,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
 	.dle_func_en = dle_func_en_be,
 	.dle_clk_en = dle_clk_en_be,
 	.bf_assoc = rtw89_mac_bf_assoc_be,
+	.mlo_link_cfg = rtw89_mac_mlo_link_cfg_be,
+	.init_drv_txen = rtw89_mac_init_drv_txen_be,
 
 	.typ_fltr_opt = rtw89_mac_typ_fltr_opt_be,
 	.cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_be,
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index 40bac65dd8ed..47e055b38b14 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -223,7 +223,7 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev)
 		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
 			rtw89_leave_lps_vif(rtwdev, rtwvif_link);
 
-	rtw89_fw_h2c_init_trx_protect(rtwdev);
+	rtw89_core_config_active_bands(rtwdev);
 }
 
 void rtw89_enter_ips(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 4bee9f66038c..fc71d8d87b57 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -6917,6 +6917,7 @@
 #define B_BE_CTN_TXEN_CPUMGQ BIT(10)
 #define B_BE_CTN_TXEN_MGQ1 BIT(9)
 #define B_BE_CTN_TXEN_MGQ BIT(8)
+#define B_BE_CTN_TXEN_ACQ GENMASK(7, 0)
 #define B_BE_CTN_TXEN_VO_1 BIT(7)
 #define B_BE_CTN_TXEN_VI_1 BIT(6)
 #define B_BE_CTN_TXEN_BK_1 BIT(5)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index a7facfe96884..4f08084026b9 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -2510,6 +2510,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
 	.read_phycap		= rtw8851b_read_phycap,
 	.fem_setup		= NULL,
 	.data_setup		= NULL,
+	.cfg_hw_mlo		= NULL,
 	.rfe_gpio		= rtw8851b_rfe_gpio,
 	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8851b_rfk_init,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 3b5e3c178440..8742adcb1b83 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2290,6 +2290,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
 	.fem_setup		= rtw8852a_fem_setup,
 	.data_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.cfg_hw_mlo		= NULL,
 	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8852a_rfk_init,
 	.rfk_init_late		= NULL,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 138f499af677..0265026c3450 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -883,6 +883,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
 	.fem_setup		= NULL,
 	.data_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.cfg_hw_mlo		= NULL,
 	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8852b_rfk_init,
 	.rfk_init_late		= NULL,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index bdcce2e94f99..ab2694095951 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -3091,6 +3091,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
 	.fem_setup		= NULL,
 	.data_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.cfg_hw_mlo		= NULL,
 	.rfk_hw_init		= NULL,
 	.rfk_init		= rtw8852c_rfk_init,
 	.rfk_init_late		= NULL,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index a3b5da979768..5521a6a78318 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -3141,6 +3141,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
 	.fem_setup		= NULL,
 	.data_setup		= NULL,
 	.rfe_gpio		= NULL,
+	.cfg_hw_mlo		= NULL,
 	.rfk_hw_init		= rtw8922a_rfk_hw_init,
 	.rfk_init		= rtw8922a_rfk_init,
 	.rfk_init_late		= rtw8922a_rfk_init_late,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 2bc46be72e0a..4175aeceef8d 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -2702,6 +2702,12 @@ static void __rtw8922d_rfk_init_late(struct rtw89_dev *rtwdev,
 		rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58);
 }
 
+static void rtw8922d_cfg_hw_mlo(struct rtw89_dev *rtwdev)
+{
+	rtw8922d_ctrl_mlo(rtwdev, rtwdev->mlo_dbcc_mode, true);
+	rtw8922d_rfk_mlo_ctrl(rtwdev);
+}
+
 static void rtw8922d_rfk_init_late(struct rtw89_dev *rtwdev)
 {
 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
@@ -3683,6 +3689,7 @@ static const struct rtw89_chip_ops rtw8922d_chip_ops = {
 	.fem_setup		= NULL,
 	.data_setup		= rtw8922d_data_setup,
 	.rfe_gpio		= NULL,
+	.cfg_hw_mlo		= rtw8922d_cfg_hw_mlo,
 	.rfk_hw_init		= rtw8922d_rfk_hw_init,
 	.rfk_init		= rtw8922d_rfk_init,
 	.rfk_init_late		= rtw8922d_rfk_init_late,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 10/11] wifi: rtw89: 8922d: enable dynamic antenna gain
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (8 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 09/11] wifi: rtw89: Update sequence for MLO link switch Ping-Ke Shih
@ 2026-11-12  6:05 ` Ping-Ke Shih
  2026-11-12  6:06 ` [PATCH rtw-next 11/11] wifi: rtw89: phy: fix antenna gain unit in debug output Ping-Ke Shih
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Kuan-Chung Chen <damon.chen@realtek.com>

RTL8922D supports dynamic antenna gain compensation via ACPI Realtek
Antenna Gain (RTAG), so turn on the flag in its chip info.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/rtw8922d.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 4175aeceef8d..eaa12f7562b0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -3808,7 +3808,7 @@ const struct rtw89_chip_info rtw8922d_chip_info = {
 				  BIT(NL80211_CHAN_WIDTH_80) |
 				  BIT(NL80211_CHAN_WIDTH_160),
 	.support_unii4		= true,
-	.support_ant_gain	= false,
+	.support_ant_gain	= true,
 	.support_tas		= false,
 	.support_sar_by_ant	= true,
 	.support_noise		= false,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH rtw-next 11/11] wifi: rtw89: phy: fix antenna gain unit in debug output
  2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
                   ` (9 preceding siblings ...)
  2026-11-12  6:05 ` [PATCH rtw-next 10/11] wifi: rtw89: 8922d: enable dynamic antenna gain Ping-Ke Shih
@ 2026-11-12  6:06 ` Ping-Ke Shih
  10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2026-11-12  6:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601, damon.chen, phhuang, kevin_yang

From: Kuan-Chung Chen <damon.chen@realtek.com>

The antenna gain offset is in RF TX power precision, so shift
right by txpwr_factor_rf before printing it.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/phy.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 795920b899d9..bbbe43e1ea04 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2391,6 +2391,7 @@ EXPORT_SYMBOL(rtw89_phy_ant_gain_pwr_offset);
 int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
 			 const struct rtw89_chan *chan)
 {
+	u8 factor = rtwdev->chip->txpwr_factor_rf;
 	char *p = buf, *end = buf + bufsz;
 	s8 offset_patha, offset_pathb;
 
@@ -2402,8 +2403,8 @@ int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
 	offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
 	offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq);
 
-	p += scnprintf(p, end - p, "ChainA offset: %d dBm\n", offset_patha);
-	p += scnprintf(p, end - p, "ChainB offset: %d dBm\n", offset_pathb);
+	p += scnprintf(p, end - p, "ChainA offset: %d dBm\n", offset_patha >> factor);
+	p += scnprintf(p, end - p, "ChainB offset: %d dBm\n", offset_pathb >> factor);
 
 out:
 	return p - buf;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-11-12  6:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-12  6:05 [PATCH rtw-next 00/11] wifi: rtw89: correct no 2GHz band condition, update RTL8922D settings Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 01/11] wifi: rtw89: coex: add a notify entry for dynamic MLO RF-path switch Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 02/11] wifi: rtw89: pci: reclaim TXBD before fully draining Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 03/11] wifi: rtw89: 8922d: use efuse bias for CCK RX gain Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 04/11] wifi: rtw89: 8922d: set CFR clip threshold while setting channel Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 05/11] wifi: rtw89: 8922d: correct thermal trim range to -16~+16 programmed in efuse Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 06/11] wifi: rtw89: introduce bitmap of supported bands to deal with quirks Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 07/11] wifi: rtw89: get default channel based on supported bands Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 08/11] wifi: rtw89: fix band assignment in rtw89_core_update_rx_freq_from_ie() Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 09/11] wifi: rtw89: Update sequence for MLO link switch Ping-Ke Shih
2026-11-12  6:05 ` [PATCH rtw-next 10/11] wifi: rtw89: 8922d: enable dynamic antenna gain Ping-Ke Shih
2026-11-12  6:06 ` [PATCH rtw-next 11/11] wifi: rtw89: phy: fix antenna gain unit in debug output Ping-Ke Shih

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox